Skip to content

Hibernate ORM tries to connect to the database on startup even with schema validation disabled #48130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

lucamolteni
Copy link
Contributor

Fixes: #30002 (comment)

To be merged after #41310 as it's based on @yrodiere Hibernate 7 branch, creating a Draft PR

Based on the original work of https://github.com/xdev-software https://github.com/quarkusio/quarkus/pull/47695/files

This handles some of the issues addressed in #30002 (comment)

Done:

  • A start-offline setting
  • Code that turns this setting into hibernate.boot.allow_jdbc_metadata_access=*.
    io.quarkus.hibernate.orm.runtime.HibernateOrmRuntimeConfigPersistenceUnit.HibernateOrmConfigPersistenceUnitDatabase#versionCheckEnabled should default to false when asked to start offline, and lead to an exception with a clear message when it's explicitly set to true while starting offline.
  • io.quarkus.hibernate.orm.runtime.HibernateOrmRuntimeConfigPersistenceUnit.HibernateOrmConfigPersistenceUnitSchemaManagement#strategy should default to none when asked to start offline, and lead to an exception with a clear message when it's explicitly set to anything else while starting offline.
  • A few tests (for both ORM and reactive)

Except for the one for dev services for a few reasons:

  • I haven't found a way to test it properly (yet)
  • I could find an easy way to get the runtime configuration in HibernateOrmDevServicesProcessor
  • I'm not entirely sure the offline mode should change the behaviour of dev mode. I think it's for deployment scenarios.

yrodiere and others added 20 commits May 20, 2025 14:15
These internals are changing in Hibernate ORM 7
Because:

1. We currently disallow this for identifier generators only
   through a custom initializer for the identifier generator
   factory service, but that service is disappearing in Hibernate
   ORM 7.0.0.Beta1, leaving us only the setting `hibernate.cdi.extensions`.
   to disallow CDI for identifier generators -- and anything else
   that impacts metadata creation.
2. This is needed for quarkusio#40897,
   which will move more of metadata creation to build time -- where CDI
   is just not available.
3. Implementations of affected components needing access to CDI at
   runtime (so not during metadata creation) can still do so by
   calling `Arc.container()` to retrieve the relevant beans.
…equired dependencies

With Derby moving to hibernate-community-dialects, Quarkus will need to
add this dependency automatically.
…ilder

Some of these changes probably pre-date Hibernate ORM 7.0,
we just forgot to implement them.
And remove Hibernate Commons Annotations, which isn't needed by any
Hibernate project anymore.
* Including verification for checkVersion
* Including asserts on schema management
@lucamolteni lucamolteni requested review from yrodiere and gsmet and removed request for yrodiere May 29, 2025 12:19
@quarkus-bot quarkus-bot bot added area/dependencies Pull requests that update a dependency file area/devtools Issues/PR related to maven, gradle, platform and cli tooling/plugins area/documentation area/hibernate-orm Hibernate ORM area/hibernate-search Hibernate Search area/hibernate-reactive Hibernate Reactive labels May 29, 2025
@quarkus-bot quarkus-bot bot added area/panache area/spring Issues relating to the Spring integration labels May 29, 2025
Copy link

quarkus-bot bot commented May 29, 2025

/cc @gsmet (hibernate-orm,hibernate-search), @marko-bekhta (hibernate-search)

Copy link
Member

@yrodiere yrodiere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM overall, though I have concerns about the temporary table thing -- see below.

To be merged after #41310 as it's based on @yrodiere Hibernate 7 branch, creating a Draft PR

FWIW if you're only going to address #30002 (and not #13522) in this PR, you can probably base your work on main. I don't expect anything here to require the upgrade to ORM 7, and this would allow merging your PR more quickly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure the offline mode should change the behaviour of dev mode. I think it's for deployment scenarios.

It definitely should IMO. As a rule, explicit configuration should never be ignored.

If people want Hibernate ORM to start offline in every mode, that's fine, and it can definitely make sense if they don't use dev services. Even when using dev services, I personally would want my app to behave as closely as possible to the way it will behave in production.

If people want Hibernate ORM to start offline only in prod mode, they can use %prod.quarkus.hibernate-orm.start-offline = true.

throwable -> assertThat(throwable)
.hasNoSuppressedExceptions()
.hasMessageContaining(
"Version check `quarkus.hibernate-orm.schema-management.strategy` cannot be any different than `none` when using offline mode `quarkus.hibernate-orm.database.start-offline=true`"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording seems strange, especially the "any different"... Also it has nothing to do with the version check?

I'd recommend something like this:

Suggested change
"Version check `quarkus.hibernate-orm.schema-management.strategy` cannot be any different than `none` when using offline mode `quarkus.hibernate-orm.database.start-offline=true`"));
"Schema management strategy `quarkus.hibernate-orm.schema-management.strategy` only be set to `none` when using offline mode `quarkus.hibernate-orm.database.start-offline=true`"));

@WithName("version-check.enabled")
@ConfigDocDefault("`true` if the dialect was set automatically by Quarkus, `false` if it was set explicitly")
@ConfigDocDefault("`true` if the dialect was set automatically by Quarkus, `false` if it was set explicitly, `false` in offlineMode")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, three different possibilities is starting to get ambiguous :)

Maybe:

Suggested change
@ConfigDocDefault("`true` if the dialect was set automatically by Quarkus, `false` if it was set explicitly, `false` in offlineMode")
@ConfigDocDefault("`false` if the dialect was set explicitly or if starting offline (see `start-offline`), `true` otherwise")

Optional<Boolean> versionCheckEnabled();

/**
* This value will avoid connecting to a database to fetch JDBC metadata.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think at this point it's more about disabling/disallowing these other features? Or at least that will probably be more meaningful to application developers.

Suggested change
* This value will avoid connecting to a database to fetch JDBC metadata.
* Instructs Hibernate ORM to avoid connecting to the database on startup (for schema management, temporary table creation, DB version checking, ...).
* <p>

// Allow detection of driver/database capabilities on runtime init if required
// (was disabled during static init)
runtimeSettingsBuilder.put(JdbcSettings.ALLOW_METADATA_ON_BOOT, !startsOffline);
runtimeSettingsBuilder.put(GlobalTemporaryTableStrategy.CREATE_ID_TABLES, !startsOffline);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will probably need more thoughts. If we don't create the tables, presumably something will go wrong when those tables are used.

So:

  1. When starting offline, should we consider simply overriding the temporary table kind to local? AFAIK H2 supports local temporary tables, and that was even the default before ORM 6.6: https://hibernate.atlassian.net/browse/HHH-18146 .
  2. If instead we keep "persistent" temporary tables:
    1. Should we document this in Quarkus, and explain how to work around the problem?
    2. Should we set the other setting, another setting, DROP_ID_TABLES, to false as well? If someone else created the tables, they probably wouldn't want us to drop them...
    3. Should probably report the problem to Hibernate ORM, so that "temporary" table creation is integrated into schema management (hbm2ddl)? That makes a lot more sense to me...

I'd personally go with the first option, which puts the problem away in the short term, and file a ticket about investigating the second option later.. Because regardless,

Note: Keep in mind the "temporary tables" are only used in some specific scenarios, so existing tests may not detect any problems, yet there will be problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/dependencies Pull requests that update a dependency file area/devtools Issues/PR related to maven, gradle, platform and cli tooling/plugins area/documentation area/hibernate-orm Hibernate ORM area/hibernate-reactive Hibernate Reactive area/hibernate-search Hibernate Search area/panache area/spring Issues relating to the Spring integration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Hibernate ORM tries to connect to the database on startup even with schema validation disabled
2 participants