Race condition between Hibernate PhysicalNamingStrategy and HikariCP initialization (JDBC metadata not yet available)

Hi,

I’m encountering a race condition during application startup involving:

  • custom PhysicalNamingStrategy
  • JDBC metadata access via JdbcEnvironment
  • HikariCP connection initialization

Context

Spring Boot Hibernate ORM HikariCP
3.5.6 6.2.9 default pool via Spring Boot

Problem

Our custom PhysicalNamingStrategy depends on correct JDBC metadata, specifically the current schema resolved via Hibernate’s JdbcEnvironment.

However, during startup:

  • Hibernate invokes PhysicalNamingStrategy early in the bootstrap process
  • At that moment, sometimes HikariCP has not yet established a connection
  • As a result, Hibernate falls back to: hibernate.default_schema
  • This value is not equal to the actual schema resolved from the database connection
  • This leads to incorrect physical table name resolution.

We rely on dynamic schema resolution (based on DB/user context), and:

  • hibernate.default_schema is a shared/common schema
  • actual schema is connection-specific
  • mismatch causes incorrect SQL generation

We cannot change hibernate.default_schema, because:

  • it is required for shared tables
  • changing it breaks existing queries

Simplified code example

Custom naming strategy

public class CustomPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl {
 {

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {

  
        String currentSchema = context.getCurrentSchema(); // fallback is done here, since JdbcEnvironment returns the default_schema value if the JDBC metadata is not available at that moment
...
       
    }
}

Jpa configuration

@AutoConfiguration
public class InfrastructureJpaAutoConfiguration {
  
  @Bean
  @ConditionalOnMissingBean
  @SuppressWarnings("java:S1192")
  public JpaProperties jpaProperties(Environment environment) {
    JpaProperties jpaProperties = new JpaProperties();
    jpaProperties.setDatabase(Database.ORACLE);
    jpaProperties.getProperties().put("hibernate.dialect", "org.hibernate.dialect.Oracle12cDialect");

    ...
    return jpaProperties;
}

Question

Is there a guaranteed way to ensure that PhysicalNamingStrategy is executed only after JDBC metadata is fully available?

Any guidance on correct lifecycle expectations or recommended patterns would be highly appreciated. Thanks.

I guess you debugged or looked into the code already. Do you have a hint where this might go wrong?

Hi @beikov, thanks for your comment.

Yes, I looked into the code, and based on the description of JdbcEnvironment.getCurrentSchema(), this is expected behavior. If JdbcEnvironmentInitiator fails to access the JDBC metadata during initialization, it will fall back to default values, including hibernate.default_schema, which in case of our custom table name strategy, can lead to incorrect table name resolution.

In practice, this race condition is difficult to reproduce and catch some debug logs, since it depends on the exact timing of HikariCP connection initialization versus Hibernate’s bootstrap. And usually after restarting the app, everything works as expected again,..

Given this, it might be worth discussing if there’s a way to ensure that metadata is available before the strategy executes, or, as a last option, whether we should rely on real JDBC metadata in the PhysicalNamingStrategy at all,…

I found the following Hikari config: initializationFailTimeout
Our value here is 1ms (default). By description of this property, if we were to increase it, we could potentially decrease the risk of this Hikari/Hibernate race condition.

I’m having a hard time understanding what is happening. You can configure hibernate.boot.allow_jdbc_metadata_access=require to make sure that the app fails if the JDBC metadata is not accessible.
What I don’t understand is where the concurrency problem should be. If HikariCP hands out a connection that is not established yet and fails on first access, that is a problem of HikariCP, not Hibernate ORM. Maybe you can clarify what you think is the problem?

Let me try to clarify the scenario more concretely.

I’m observing inconsistent behavior during application startup where a custom naming strategy depends on the connection’s schema name, which is not always accessible at the time table names are resolved.

Case 1 (expected) - 99%

  • Hibernate initializes JdbcEnvironment
  • JDBC metadata is accessible
  • JdbcEnvironment context.getCurrentSchema() returns the actual schema name from the connection
  • custom PhysicalNamingStrategy resolves table names correctly

Case 2 (problematic - not easily reproducible) - 1% or less :confused:

  • Hibernate initializes JdbcEnvironment
  • JDBC metadata is not accessible at that moment
  • JdbcEnvironment context.getCurrentSchema() falls back to hibernate.default_schema
  • custom PhysicalNamingStrategyuses that value
  • table names are resolved incorrectly

So the outcome depends on whether metadata access succeeds at that point during bootstrap.

Our custom PhysicalNamingStrategy relies on context.getCurrentSchema(), which makes this behavior non-deterministic.

I’m not suggesting this is a Hibernate issue, but rather asking whether there is a way to ensure that context.getCurrentSchema() consistently returns the schema resolved from the JDBC connection, instead of falling back to hibernate.default_schema.

Like I already wrote, you can configure hibernate.boot.allow_jdbc_metadata_access=require to make sure that the app fails at startup if the JDBC metadata is not accessible.
Why the metadata is not accessible is still not clear to me, but that’s not a Hibernate ORM issue.

Thanks for the hint and for taking the time to look into this.