diff --git a/docs/src/main/asciidoc/hibernate-orm.adoc b/docs/src/main/asciidoc/hibernate-orm.adoc index febded3b4cb11..f41dd334d1faa 100644 --- a/docs/src/main/asciidoc/hibernate-orm.adoc +++ b/docs/src/main/asciidoc/hibernate-orm.adoc @@ -200,8 +200,9 @@ but must be lower than or equal to the version of any database your application [NOTE] ==== -When a version is set explicitly, -Quarkus will try to check this version against the actual database version on startup, +As described above, the version can either be preconfigured explicitly via a `quarkus.datasource.db-version` configuration property, +or implicitly set by the Quarkus build process to a minimum supported version of the database. +Quarkus will try to check this preconfigured version against the actual database version on startup, leading to a startup failure when the actual version is lower. This is because Hibernate ORM may generate SQL that is invalid diff --git a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactory.java b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactory.java index 7c58e3d1cd064..20274226c7823 100644 --- a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactory.java +++ b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactory.java @@ -29,13 +29,13 @@ public class QuarkusRuntimeInitDialectFactory implements DialectFactory { private final String persistenceUnitName; private final Dialect dialect; private final Optional datasourceName; - private final Optional buildTimeDbVersion; + private final DatabaseVersion buildTimeDbVersion; private boolean triedToRetrieveDbVersion = false; private Optional actualDbVersion = Optional.empty(); public QuarkusRuntimeInitDialectFactory(String persistenceUnitName, Dialect dialect, - Optional datasourceName, Optional buildTimeDbVersion) { + Optional datasourceName, DatabaseVersion buildTimeDbVersion) { this.persistenceUnitName = persistenceUnitName; this.dialect = dialect; this.datasourceName = datasourceName; @@ -45,29 +45,25 @@ public QuarkusRuntimeInitDialectFactory(String persistenceUnitName, Dialect dial @Override public Dialect buildDialect(Map configValues, DialectResolutionInfoSource resolutionInfoSource) throws HibernateException { - if (buildTimeDbVersion.isPresent() && actualDbVersion.isEmpty()) { + if (actualDbVersion.isEmpty()) { this.actualDbVersion = retrieveDbVersion(resolutionInfoSource); } return dialect; } public void checkActualDbVersion() { - if (buildTimeDbVersion.isEmpty()) { - // Nothing to check - return; - } if (!triedToRetrieveDbVersion) { LOG.warnf("Persistence unit %1$s: Could not retrieve the database version to check it is at least %2$s", - persistenceUnitName, DialectVersions.toString(buildTimeDbVersion.get())); + persistenceUnitName, DialectVersions.toString(buildTimeDbVersion)); return; } - if (actualDbVersion.isPresent() && buildTimeDbVersion.get().isAfter(actualDbVersion.get())) { + if (actualDbVersion.isPresent() && buildTimeDbVersion.isAfter(actualDbVersion.get())) { throw new ConfigurationException(String.format(Locale.ROOT, "Persistence unit '%1$s' was configured to run with a database version" + " of at least '%2$s', but the actual version is '%3$s'." + " Consider upgrading your database.", persistenceUnitName, - DialectVersions.toString(buildTimeDbVersion.get()), DialectVersions.toString(actualDbVersion.get())) + DialectVersions.toString(buildTimeDbVersion), DialectVersions.toString(actualDbVersion.get())) // It shouldn't be possible to reach this code if datasourceName is empty, // but just let's be safe... + (datasourceName.isEmpty() ? "" @@ -93,7 +89,7 @@ private Optional retrieveDbVersion(DialectResolutionInfoSource databaseMetadata.getDatabaseMinorVersion())); } catch (RuntimeException | SQLException e) { LOG.warnf(e, "Persistence unit %1$s: Could not retrieve the database version to check it is at least %2$s", - persistenceUnitName, buildTimeDbVersion.get()); + persistenceUnitName, buildTimeDbVersion); return Optional.empty(); } } diff --git a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactoryInitiator.java b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactoryInitiator.java index 00d23fbbed8cf..6afc598a97129 100644 --- a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactoryInitiator.java +++ b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRuntimeInitDialectFactoryInitiator.java @@ -16,17 +16,16 @@ public class QuarkusRuntimeInitDialectFactoryInitiator implements StandardServic private final String persistenceUnitName; private final Dialect dialect; private final Optional datasourceName; - private final Optional buildTimeDbVersion; + private final DatabaseVersion buildTimeDbVersion; public QuarkusRuntimeInitDialectFactoryInitiator(String persistenceUnitName, Dialect dialect, RecordedConfig recordedConfig) { this.persistenceUnitName = persistenceUnitName; this.dialect = dialect; this.datasourceName = recordedConfig.getDataSource(); - this.buildTimeDbVersion = recordedConfig.getDbVersion().isPresent() - // This is the same version, but parsed in a dialect-specific way. - ? Optional.of(dialect.getVersion()) - : Optional.empty(); + // We set the version from the dialect since if it wasn't provided explicitly through the `recordedConfig.getDbVersion()` + // then the version from `DialectVersions.Defaults` will be used: + this.buildTimeDbVersion = dialect.getVersion(); } @Override