Skip to content

Commit cf2acb1

Browse files
authored
Merge pull request #31701 from yrodiere/i31474-db-min-version
Fix deprecation warnings related to ORM dialects and add `quarkus.datasource.db-version` as a dialect version hint
2 parents d6e0af8 + b0de52b commit cf2acb1

File tree

63 files changed

+1597
-206
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1597
-206
lines changed

bom/application/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
<httpasync.version>4.1.5</httpasync.version>
127127
<cronutils.version>9.2.0</cronutils.version>
128128
<quartz.version>2.3.2</quartz.version>
129-
<h2.version>2.1.214</h2.version> <!-- When updating, needs to be matched in io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect -->
129+
<h2.version>2.1.214</h2.version> <!-- When updating, needs to be matched in io.quarkus.hibernate.orm.runtime.config.DialectVersions -->
130130
<postgresql-jdbc.version>42.5.4</postgresql-jdbc.version>
131131
<mariadb-jdbc.version>3.1.2</mariadb-jdbc.version>
132132
<mysql-jdbc.version>8.0.30</mysql-jdbc.version>

docs/src/main/asciidoc/hibernate-orm.adoc

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ For a list of the items that you can set in `{config-file}`, see xref:hibernate-
102102

103103
An `EntityManagerFactory` will be created based on the Quarkus `datasource` configuration as long as the Hibernate ORM extension is listed among your project dependencies.
104104

105-
Unless you set one explicitly, the dialect will be selected based on the JDBC driver.
105+
The dialect will be selected and configured automatically based on your datasource;
106+
you may want to <<hibernate-dialect,configure it to more precisely match your database>>.
106107

107108
You can then happily inject your `EntityManager`:
108109

@@ -165,6 +166,93 @@ WARNING: Make sure to wrap methods modifying your database (e.g. `entity.persist
165166
CDI bean method `@Transactional` will do that for you and make that method a transaction boundary. We recommend doing
166167
so at your application entry point boundaries like your REST endpoint controllers.
167168

169+
[[hibernate-dialect]]
170+
=== Dialect
171+
172+
[[hibernate-dialect-supported-databases]]
173+
==== Supported databases
174+
175+
For xref:datasource.adoc#default-datasource[supported databases],
176+
the link:{orm-doc-url-prefix}##database-dialect[Hibernate ORM dialect]
177+
does not need to be set explicitly:
178+
it is selected automatically based on the datasource.
179+
180+
By default, the dialect is configured to target the minimum supported version of the database.
181+
182+
In order for Hibernate ORM to generate more efficient SQL,
183+
to avoid workarounds and to take advantage of more database features,
184+
you can set the database version explicitly:
185+
186+
[source,properties]
187+
.`{config-file}` with an explicit `db-version`
188+
----
189+
quarkus.datasource.db-kind = postgresql
190+
quarkus.datasource.db-version = 14.0 <1>
191+
quarkus.datasource.username = hibernate
192+
quarkus.datasource.password = hibernate
193+
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/hibernate_db
194+
----
195+
<1> Set the database version. The Hibernate ORM dialect will target that version.
196+
197+
As a rule, the version set here should be as high as possible,
198+
but must be lower than or equal to the version of any database your application will connect to.
199+
200+
[NOTE]
201+
====
202+
When a version is set explicitly,
203+
Quarkus will try to check this version against the actual database version on startup,
204+
leading to a startup failure when the actual version is lower.
205+
206+
This is because Hibernate ORM may generate SQL that is invalid
207+
for versions of the database older than what is configured,
208+
which would lead to runtime exceptions.
209+
210+
If the database cannot be reached, a warning will be logged but startup will proceed.
211+
====
212+
213+
[[hibernate-dialect-other-databases]]
214+
==== Other databases
215+
216+
If xref:datasource.adoc#other-databases[your database does not have a corresponding Quarkus extension],
217+
or if the defaults do not match your needs for some reason,
218+
you will need to set the link:{orm-doc-url-prefix}##database-dialect[Hibernate ORM dialect] explicitly:
219+
220+
[source,properties]
221+
.`{config-file}` with an explicit `dialect`
222+
----
223+
quarkus.datasource.db-kind = postgresql
224+
quarkus.datasource.username = hibernate
225+
quarkus.datasource.password = hibernate
226+
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:26257/hibernate_db
227+
228+
quarkus.hibernate-orm.dialect=org.hibernate.dialect.CockroachDialect <1>
229+
----
230+
<1> Set the Hibernate ORM dialect.
231+
232+
[WARNING]
233+
====
234+
In that case, keep in mind that the JDBC driver or Hibernate ORM dialect
235+
may not work properly in GraalVM native executables.
236+
====
237+
238+
As with <<hibernate-dialect-supported-databases,supported databases>>,
239+
you can configure the DB version explicitly to get the most out of Hibernate ORM:
240+
241+
[source,properties]
242+
.`{config-file}` with an explicit `dialect` and `db-version`
243+
----
244+
quarkus.datasource.db-kind = postgresql
245+
quarkus.datasource.db-version = 22.2 <1>
246+
quarkus.datasource.username = hibernate
247+
quarkus.datasource.password = hibernate
248+
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:26257/hibernate_db
249+
250+
quarkus.hibernate-orm.dialect=org.hibernate.dialect.CockroachDialect <2>
251+
----
252+
<1> Set the database version. The Hibernate ORM dialect will target that version.
253+
Since we're targeting CockroachDB here, we're passing the CockroachDB version, not the PostgreSQL version.
254+
<2> Set the Hibernate ORM dialect.
255+
168256
[[hibernate-configuration-properties]]
169257
=== Hibernate ORM configuration properties
170258

@@ -417,7 +505,7 @@ difference is that you would specify your Hibernate ORM configuration in `META-I
417505
418506
<properties>
419507
<!-- Connection specific -->
420-
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect"/>
508+
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
421509
422510
<property name="hibernate.show_sql" value="true"/>
423511
<property name="hibernate.format_sql" value="true"/>

extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/AgroalProcessor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ private DataSourceSupport getDataSourceSupport(
186186
String dataSourceName = aggregatedDataSourceBuildTimeConfig.getName();
187187
dataSourceSupportEntries.put(dataSourceName,
188188
new DataSourceSupport.Entry(dataSourceName, aggregatedDataSourceBuildTimeConfig.getDbKind(),
189+
aggregatedDataSourceBuildTimeConfig.getDataSourceConfig().dbVersion,
189190
aggregatedDataSourceBuildTimeConfig.getResolvedDriverClass(),
190191
aggregatedDataSourceBuildTimeConfig.isDefault()));
191192
}
@@ -274,6 +275,7 @@ void generateDataSourceBeans(AgroalRecorder recorder,
274275

275276
jdbcDataSource.produce(new JdbcDataSourceBuildItem(dataSourceName,
276277
entry.getValue().resolvedDbKind,
278+
entry.getValue().dbVersion,
277279
entry.getValue().isDefault));
278280
}
279281
}

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSourceSupport.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.quarkus.agroal.runtime;
22

33
import java.util.Map;
4+
import java.util.Optional;
45

56
public class DataSourceSupport {
67

@@ -17,13 +18,16 @@ public DataSourceSupport(boolean disableSslSupport, boolean mpMetricsPresent, Ma
1718
public static class Entry {
1819
public final String dataSourceName;
1920
public final String resolvedDbKind;
21+
public final Optional<String> dbVersion;
2022
public final String resolvedDriverClass;
2123
public final boolean isDefault;
2224

23-
public Entry(String dataSourceName, String resolvedDbKind, String resolvedDriverClass,
25+
public Entry(String dataSourceName, String resolvedDbKind, Optional<String> dbVersion,
26+
String resolvedDriverClass,
2427
boolean isDefault) {
2528
this.dataSourceName = dataSourceName;
2629
this.resolvedDbKind = resolvedDbKind;
30+
this.dbVersion = dbVersion;
2731
this.resolvedDriverClass = resolvedDriverClass;
2832
this.isDefault = isDefault;
2933
}

extensions/agroal/spi/src/main/java/io/quarkus/agroal/spi/JdbcDataSourceBuildItem.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.quarkus.agroal.spi;
22

3+
import java.util.Optional;
4+
35
import io.quarkus.builder.item.MultiBuildItem;
46

57
/**
@@ -14,11 +16,13 @@ public final class JdbcDataSourceBuildItem extends MultiBuildItem {
1416

1517
private final String dbKind;
1618

19+
private final Optional<String> dbVersion;
1720
private final boolean isDefault;
1821

19-
public JdbcDataSourceBuildItem(String name, String kind, boolean isDefault) {
22+
public JdbcDataSourceBuildItem(String name, String kind, Optional<String> dbVersion, boolean isDefault) {
2023
this.name = name;
2124
this.dbKind = kind;
25+
this.dbVersion = dbVersion;
2226
this.isDefault = isDefault;
2327
}
2428

@@ -30,6 +34,10 @@ public String getDbKind() {
3034
return dbKind;
3135
}
3236

37+
public Optional<String> getDbVersion() {
38+
return dbVersion;
39+
}
40+
3341
public boolean isDefault() {
3442
return isDefault;
3543
}

extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DataSourceBuildTimeConfig.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,38 @@ public class DataSourceBuildTimeConfig {
1616
@ConvertWith(DatabaseKindConverter.class)
1717
public Optional<String> dbKind = Optional.empty();
1818

19+
/**
20+
* The version of the database we will connect to (e.g. '10.0').
21+
*
22+
* CAUTION: The version number set here should follow the same numbering scheme
23+
* as the string returned by `java.sql.DatabaseMetaData#getDatabaseProductVersion()`
24+
* for your database's JDBC driver.
25+
* This numbering scheme may be different from the most popular one for your database;
26+
* for example Microsoft SQL Server 2016 would be version `13`.
27+
*
28+
* As a rule, the version set here should be as high as possible,
29+
* but must be lower than or equal to the version of any database your application will connect to.
30+
*
31+
* A high version will allow better performance and using more features
32+
* (e.g. Hibernate ORM may generate more efficient SQL,
33+
* avoid workarounds and take advantage of more database features),
34+
* but if it is higher than the version of the database you want to connect to,
35+
* it may lead to runtime exceptions
36+
* (e.g. Hibernate ORM may generate invalid SQL that your database will reject).
37+
*
38+
* Some extensions (like the Hibernate ORM extension)
39+
* will try to check this version against the actual database version on startup,
40+
* leading to a startup failure when the actual version is lower
41+
* or simply a warning in case the database cannot be reached.
42+
*
43+
* The default for this property is specific to each extension;
44+
* the Hibernate ORM extension will default to the oldest version it supports.
45+
*
46+
* @asciidoclet
47+
*/
48+
@ConfigItem
49+
public Optional<String> dbVersion = Optional.empty();
50+
1951
/**
2052
* Configuration for DevServices. DevServices allows Quarkus to automatically start a database in dev and test mode.
2153
*/

extensions/hibernate-orm/deployment-spi/src/main/java/io/quarkus/hibernate/orm/deployment/spi/DatabaseKindDialectBuildItem.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.quarkus.hibernate.orm.deployment.spi;
22

3+
import java.util.Optional;
4+
35
import io.quarkus.builder.item.MultiBuildItem;
46

57
/**
@@ -8,10 +10,33 @@
810
public final class DatabaseKindDialectBuildItem extends MultiBuildItem {
911
private final String dbKind;
1012
private final String dialect;
13+
private final Optional<String> defaultDatabaseProductVersion;
1114

15+
/**
16+
* @param dbKind The DB Kind set through {@code quarkus.datasource.db-kind}
17+
* @param dialect The corresponding dialect to set in Hibernate ORM.
18+
*/
1219
public DatabaseKindDialectBuildItem(String dbKind, String dialect) {
20+
this(dbKind, dialect, Optional.empty());
21+
}
22+
23+
/**
24+
* @param dbKind The DB Kind set through {@code quarkus.datasource.db-kind}
25+
* @param dialect The corresponding dialect to set in Hibernate ORM.
26+
* See {@code org.hibernate.dialect.Database} for information on how this name is resolved to a dialect.
27+
* @param defaultDatabaseProductVersion The default database-product-version to set in Hibernate ORM.
28+
* This is useful when the default version of the dialect in Hibernate ORM
29+
* is lower than what we expect in Quarkus.
30+
*/
31+
public DatabaseKindDialectBuildItem(String dbKind, String dialect, String defaultDatabaseProductVersion) {
32+
this(dbKind, dialect, Optional.of(defaultDatabaseProductVersion));
33+
}
34+
35+
private DatabaseKindDialectBuildItem(String dbKind, String dialect,
36+
Optional<String> defaultDatabaseProductVersion) {
1337
this.dbKind = dbKind;
1438
this.dialect = dialect;
39+
this.defaultDatabaseProductVersion = defaultDatabaseProductVersion;
1540
}
1641

1742
public String getDbKind() {
@@ -21,4 +46,8 @@ public String getDbKind() {
2146
public String getDialect() {
2247
return dialect;
2348
}
49+
50+
public Optional<String> getDefaultDatabaseProductVersion() {
51+
return defaultDatabaseProductVersion;
52+
}
2453
}

extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/Dialects.java

Lines changed: 0 additions & 29 deletions
This file was deleted.

extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfigPersistenceUnit.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -282,22 +282,29 @@ public boolean isAnyPropertySet() {
282282
public static class HibernateOrmConfigPersistenceUnitDialect {
283283

284284
/**
285-
* Class name of the Hibernate ORM dialect. The complete list of bundled dialects is available in the
285+
* Class name of the Hibernate ORM dialect.
286+
*
287+
* The complete list of bundled dialects is available in the
286288
* https://docs.jboss.org/hibernate/stable/orm/javadocs/org/hibernate/dialect/package-summary.html[Hibernate ORM
287289
* JavaDoc].
288290
*
289-
* [NOTE]
290-
* ====
291-
* Not all the dialects are supported in GraalVM native executables: we currently provide driver extensions for
292-
* PostgreSQL,
293-
* MariaDB, Microsoft SQL Server and H2.
294-
* ====
291+
* Setting the dialect directly is only recommended as a last resort:
292+
* most popular databases have a corresponding Quarkus extension,
293+
* allowing Quarkus to select the dialect automatically,
294+
* in which case you do not need to set the dialect at all,
295+
* though you may want to set
296+
* xref:datasource.adoc#quarkus-datasource_quarkus.datasource.db-version[`quarkus.datasource.db-version`] as
297+
* high as possible
298+
* to benefit from the best performance and latest features.
299+
*
300+
* If your database does not have a corresponding Quarkus extension,
301+
* you will need to set the dialect directly.
302+
* In that case, keep in mind that the JDBC driver and Hibernate ORM dialect
303+
* may not work properly in GraalVM native executables.
295304
*
296305
* @asciidoclet
297306
*/
298-
// TODO should it be dialects
299-
//TODO should it be shortcuts like "postgresql" "h2" etc
300-
@ConfigItem(name = ConfigItem.PARENT)
307+
@ConfigItem(name = ConfigItem.PARENT, defaultValueDocumentation = "selected automatically for most popular databases")
301308
@ConvertWith(TrimmedStringConverter.class)
302309
public Optional<String> dialect;
303310

0 commit comments

Comments
 (0)