Skip to content

Commit

Permalink
Change how actual DB version is checked
Browse files Browse the repository at this point in the history
  • Loading branch information
marko-bekhta authored and yrodiere committed Jun 11, 2024
1 parent f0d4d20 commit 693bfdb
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 18 deletions.
5 changes: 3 additions & 2 deletions docs/src/main/asciidoc/hibernate-orm.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Check warning on line 203 in docs/src/main/asciidoc/hibernate-orm.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/hibernate-orm.adoc", "range": {"start": {"line": 203, "column": 72}}}, "severity": "WARNING"}
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

Check warning on line 208 in docs/src/main/asciidoc/hibernate-orm.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'might (for possiblity)' or 'can (for ability)' rather than 'may' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/hibernate-orm.adoc", "range": {"start": {"line": 208, "column": 20}}}, "severity": "WARNING"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ public class QuarkusRuntimeInitDialectFactory implements DialectFactory {
private final String persistenceUnitName;
private final Dialect dialect;
private final Optional<String> datasourceName;
private final Optional<DatabaseVersion> buildTimeDbVersion;
private final DatabaseVersion buildTimeDbVersion;

private boolean triedToRetrieveDbVersion = false;
private Optional<DatabaseVersion> actualDbVersion = Optional.empty();

public QuarkusRuntimeInitDialectFactory(String persistenceUnitName, Dialect dialect,
Optional<String> datasourceName, Optional<DatabaseVersion> buildTimeDbVersion) {
Optional<String> datasourceName, DatabaseVersion buildTimeDbVersion) {
this.persistenceUnitName = persistenceUnitName;
this.dialect = dialect;
this.datasourceName = datasourceName;
Expand All @@ -45,29 +45,25 @@ public QuarkusRuntimeInitDialectFactory(String persistenceUnitName, Dialect dial
@Override
public Dialect buildDialect(Map<String, Object> 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() ? ""
Expand All @@ -93,7 +89,7 @@ private Optional<DatabaseVersion> 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();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,16 @@ public class QuarkusRuntimeInitDialectFactoryInitiator implements StandardServic
private final String persistenceUnitName;
private final Dialect dialect;
private final Optional<String> datasourceName;
private final Optional<DatabaseVersion> 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
Expand Down

0 comments on commit 693bfdb

Please sign in to comment.