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.
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
Case 2 (problematic - not easily reproducible) - 1% or less
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.