Skip to content

Commit 8957cf7

Browse files
committed
Use enums for Hibernate ORM configuration
Signed-off-by: Jan Schatteman <[email protected]>
1 parent 3758794 commit 8957cf7

File tree

6 files changed

+240
-24
lines changed

6 files changed

+240
-24
lines changed

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

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
import java.util.OptionalLong;
1010
import java.util.Set;
1111

12-
import org.hibernate.annotations.TimeZoneStorageType;
12+
import org.hibernate.annotations.TimeZoneColumn;
13+
import org.hibernate.dialect.Dialect;
1314
import org.hibernate.id.enhanced.StandardOptimizerDescriptor;
1415

1516
import io.quarkus.runtime.annotations.ConfigDocDefault;
@@ -447,7 +448,7 @@ interface Timezone {
447448
*/
448449
@WithName("default-storage")
449450
@ConfigDocDefault("default")
450-
Optional<TimeZoneStorageType> timeZoneDefaultStorage();
451+
Optional<HibernateTimeZoneStorageType> timeZoneDefaultStorage();
451452
}
452453

453454
@ConfigGroup
@@ -512,6 +513,66 @@ default boolean isAnyPropertySet() {
512513

513514
}
514515

516+
enum HibernateTimeZoneStorageType {
517+
/**
518+
* Stores the timestamp and timezone in a column of type `timestamp with time zone`.
519+
* +
520+
* Only available on some databases/dialects;
521+
* if not supported, an exception will be thrown during static initialization.
522+
*
523+
* @asciidoclet
524+
*/
525+
NATIVE("native"),
526+
/**
527+
* Does not store the timezone, and loses timezone information upon persisting.
528+
* +
529+
* Instead, normalizes the value:
530+
* * upon persisting to the database, to a timestamp in the JDBC timezone
531+
* set through `quarkus.hibernate-orm.jdbc.timezone`,
532+
* or the JVM default timezone if not set.
533+
* * upon reading back from the database, to the JVM default timezone.
534+
* +
535+
* Use this to get the legacy behavior of Quarkus 2 / Hibernate ORM 5 or older.
536+
*
537+
* @asciidoclet
538+
*/
539+
NORMALIZE("normalize"),
540+
/**
541+
* Does not store the timezone, and loses timezone information upon persisting.
542+
* +
543+
* Instead, normalizes the value to a timestamp in the UTC timezone.
544+
*
545+
* @asciidoclet
546+
*/
547+
NORMALIZE_UTC("normalize_utc"),
548+
/**
549+
* Stores the timezone in a separate column next to the timestamp column.
550+
* +
551+
* Use `@TimeZoneColumn` on the relevant entity property to customize the timezone column.
552+
*
553+
* @asciidoclet
554+
*/
555+
COLUMN("column"),
556+
/**
557+
* Equivalent to `native` if supported, `column` otherwise.
558+
*
559+
* @asciidoclet
560+
*/
561+
AUTO("auto"),
562+
/**
563+
* Equivalent to `native` if supported, `normalize-utc` otherwise.
564+
*
565+
* @asciidoclet
566+
*/
567+
DEFAULT("default");
568+
569+
private final String timezoneStorageType;
570+
571+
HibernateTimeZoneStorageType(String timezoneStorageType) {
572+
this.timezoneStorageType = timezoneStorageType;
573+
}
574+
}
575+
515576
enum IdOptimizerType {
516577
/**
517578
* Assumes the value retrieved from the table/sequence is the lower end of the pool.
@@ -557,8 +618,23 @@ interface HibernateOrmConfigPersistenceUnitQuery {
557618
int DEFAULT_QUERY_PLAN_CACHE_MAX_SIZE = 2048;
558619

559620
enum NullOrdering {
621+
/**
622+
* Null precedence not specified.
623+
*
624+
* @asciidoclet
625+
*/
560626
NONE,
627+
/**
628+
* Null values occur at the beginning of the ORDER BY clause.
629+
*
630+
* @asciidoclet
631+
*/
561632
FIRST,
633+
/**
634+
* Null values occur at the end of the ORDER BY clause.
635+
*
636+
* @asciidoclet
637+
*/
562638
LAST
563639
}
564640

@@ -756,9 +832,29 @@ default boolean isAnyPropertySet() {
756832
}
757833

758834
enum IdentifierQuotingStrategy {
835+
/**
836+
* Identifiers are not quoted.
837+
*
838+
* @asciidoclet
839+
*/
759840
NONE,
841+
/**
842+
* All identifiers are quoted.
843+
*
844+
* @asciidoclet
845+
*/
760846
ALL,
847+
/**
848+
* All identifiers, except column definitions, are quoted.
849+
*
850+
* @asciidoclet
851+
*/
761852
ALL_EXCEPT_COLUMN_DEFINITIONS,
853+
/**
854+
* Only keywords will be quoted.
855+
*
856+
* @asciidoclet
857+
*/
762858
ONLY_KEYWORDS
763859
}
764860

@@ -782,20 +878,28 @@ interface HibernateOrmConfigPersistenceValidation {
782878

783879
enum ValidationMode {
784880
/**
785-
* If a Bean Validation provider is present then behaves as if both {@link ValidationMode#CALLBACK} and
786-
* {@link ValidationMode#DDL} modes are configured. Otherwise, same as {@link ValidationMode#NONE}.
881+
* If a Bean Validation provider is present then behaves as if both `ValidationMode#CALLBACK` and
882+
* `ValidationMode#DDL` modes are configured. Otherwise, same as `ValidationMode#NONE`.
883+
*
884+
* @asciidoclet
787885
*/
788886
AUTO,
789887
/**
790888
* Bean Validation will perform the lifecycle event validation.
889+
*
890+
* @asciidoclet
791891
*/
792892
CALLBACK,
793893
/**
794894
* Bean Validation constraints will be considered for the DDL operations.
895+
*
896+
* @asciidoclet
795897
*/
796898
DDL,
797899
/**
798900
* Bean Validation integration will be disabled.
901+
*
902+
* @asciidoclet
799903
*/
800904
NONE
801905
}

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/FastBootHibernatePersistenceProvider.java

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

3+
import static io.quarkus.hibernate.orm.runtime.HibernateOrmRuntimeConfigPersistenceUnit.HibernateGenerationStrategy.getString;
4+
35
import java.util.Collections;
46
import java.util.HashSet;
57
import java.util.List;
@@ -477,8 +479,10 @@ private static void injectDataSource(String persistenceUnitName, String dataSour
477479
private static void injectRuntimeConfiguration(HibernateOrmRuntimeConfigPersistenceUnit persistenceUnitConfig,
478480
Builder runtimeSettingsBuilder) {
479481

480-
String generationStrategy = persistenceUnitConfig.schemaManagement().strategy();
481-
if (!"none".equals(generationStrategy) && persistenceUnitConfig.database().startOffline()) {
482+
HibernateOrmRuntimeConfigPersistenceUnit.HibernateGenerationStrategy generationStrategy = persistenceUnitConfig
483+
.schemaManagement().strategy();
484+
if (!HibernateOrmRuntimeConfigPersistenceUnit.HibernateGenerationStrategy.NONE.equals(generationStrategy)
485+
&& persistenceUnitConfig.database().startOffline()) {
482486
throw new PersistenceException(
483487
"When using offline mode with `quarkus.hibernate-orm.database.start-offline=true`, the schema management strategy `quarkus.hibernate-orm.schema-management.strategy` must be unset or set to `none`");
484488
}
@@ -491,8 +495,8 @@ private static void injectRuntimeConfiguration(HibernateOrmRuntimeConfigPersiste
491495
}
492496

493497
runtimeSettingsBuilder.put(AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION,
494-
persistenceUnitConfig.database().generation().generation()
495-
.orElse(generationStrategy));
498+
getString(persistenceUnitConfig.database().generation().generation()
499+
.orElse(generationStrategy)));
496500

497501
runtimeSettingsBuilder.put(AvailableSettings.JAKARTA_HBM2DDL_CREATE_SCHEMAS,
498502
String.valueOf(persistenceUnitConfig.database().generation().createSchemas()
@@ -507,7 +511,7 @@ private static void injectRuntimeConfiguration(HibernateOrmRuntimeConfigPersiste
507511
runtimeSettingsBuilder.put(AvailableSettings.HBM2DDL_SCRIPTS_CREATE_APPEND, "false");
508512

509513
runtimeSettingsBuilder.put(AvailableSettings.JAKARTA_HBM2DDL_SCRIPTS_ACTION,
510-
persistenceUnitConfig.scripts().generation().generation());
514+
getString(persistenceUnitConfig.scripts().generation().generation()));
511515

512516
if (persistenceUnitConfig.scripts().generation().createTarget().isPresent()) {
513517
runtimeSettingsBuilder.put(AvailableSettings.JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET,
@@ -549,7 +553,7 @@ private static void injectRuntimeConfiguration(HibernateOrmRuntimeConfigPersiste
549553
}
550554

551555
runtimeSettingsBuilder.put(HibernateHints.HINT_FLUSH_MODE,
552-
persistenceUnitConfig.flush().mode());
556+
persistenceUnitConfig.flush().mode().getHibernateFlushMode());
553557
}
554558

555559
}

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRecorder.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,15 @@ private SessionFactory getSessionFactoryFromContext(SyntheticCreationalContext<?
287287
public void doValidation(String puName) {
288288
HibernateOrmRuntimeConfigPersistenceUnit hibernateOrmRuntimeConfigPersistenceUnit = runtimeConfig.getValue()
289289
.persistenceUnits().get(puName);
290-
String schemaManagementStrategy = hibernateOrmRuntimeConfigPersistenceUnit.database().generation().generation()
290+
HibernateOrmRuntimeConfigPersistenceUnit.HibernateGenerationStrategy schemaManagementStrategy = hibernateOrmRuntimeConfigPersistenceUnit
291+
.database().generation().generation()
291292
.orElse(hibernateOrmRuntimeConfigPersistenceUnit.schemaManagement().strategy());
292293

293294
boolean startsOffline = hibernateOrmRuntimeConfigPersistenceUnit.database().startOffline();
294295

295296
//if hibernate is already managing the schema or if we're in offline mode we don't do this
296-
if (!"none".equals(schemaManagementStrategy) || startsOffline) {
297+
if (!HibernateOrmRuntimeConfigPersistenceUnit.HibernateGenerationStrategy.NONE.equals(schemaManagementStrategy)
298+
|| startsOffline) {
297299
return;
298300
}
299301
new Thread(new Runnable() {

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/HibernateOrmRuntimeConfigPersistenceUnit.java

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import java.util.Map;
44
import java.util.Optional;
55

6+
import jakarta.persistence.FlushModeType;
7+
68
import org.hibernate.FlushMode;
9+
import org.hibernate.Session;
10+
import org.hibernate.Transaction;
711

812
import io.quarkus.runtime.annotations.ConfigDocDefault;
913
import io.quarkus.runtime.annotations.ConfigDocMapKey;
@@ -157,9 +161,8 @@ interface HibernateOrmConfigPersistenceUnitSchemaManagement {
157161
*
158162
* @asciidoclet
159163
*/
160-
@WithConverter(TrimmedStringConverter.class)
161164
@WithDefault("none")
162-
String strategy();
165+
HibernateGenerationStrategy strategy();
163166

164167
/**
165168
* If Hibernate ORM should create the schemas automatically (for databases supporting them).
@@ -188,6 +191,60 @@ interface HibernateOrmConfigPersistenceUnitSchemaManagement {
188191
Optional<@WithConverter(TrimmedStringConverter.class) String> extraPhysicalTableTypes();
189192
}
190193

194+
enum HibernateGenerationStrategy {
195+
/**
196+
* No schema action.
197+
*
198+
* @asciidoclet
199+
*/
200+
NONE("none"),
201+
/**
202+
* Create the schema.
203+
*
204+
* @asciidoclet
205+
*/
206+
CREATE("create"),
207+
/**
208+
* Drop and then recreate the schema.
209+
*
210+
* @asciidoclet
211+
*/
212+
DROP_AND_CREATE("drop-and-create"),
213+
/**
214+
* Drop the schema.
215+
*
216+
* @asciidoclet
217+
*/
218+
DROP("drop"),
219+
/**
220+
* Update (alter) the database schema.
221+
*
222+
* @asciidoclet
223+
*/
224+
UPDATE("update"),
225+
/**
226+
* Validate the database schema.
227+
*
228+
* @asciidoclet
229+
*/
230+
VALIDATE("validate");
231+
232+
private final String schemaGenerationString;
233+
234+
HibernateGenerationStrategy(String schemaGenerationString) {
235+
this.schemaGenerationString = schemaGenerationString;
236+
}
237+
238+
public static String getString(HibernateGenerationStrategy strategy) {
239+
return strategy.toString();
240+
}
241+
242+
@Override
243+
public String toString() {
244+
return schemaGenerationString;
245+
}
246+
}
247+
191248
@ConfigGroup
192249
@Deprecated(forRemoval = true, since = "3.22")
193250
interface HibernateOrmConfigPersistenceUnitDatabaseGeneration {
@@ -204,7 +261,7 @@ interface HibernateOrmConfigPersistenceUnitDatabaseGeneration {
204261
*/
205262
@WithParentName
206263
@Deprecated(forRemoval = true, since = "3.22")
207-
Optional<@WithConverter(TrimmedStringConverter.class) String> generation();
264+
Optional<HibernateGenerationStrategy> generation();
208265

209266
/**
210267
* If Hibernate ORM should create the schemas automatically (for databases supporting them).
@@ -229,8 +286,7 @@ interface HibernateOrmConfigPersistenceUnitScriptGeneration {
229286
*/
230287
@WithParentName
231288
@WithDefault("none")
232-
@WithConverter(TrimmedStringConverter.class)
233-
String generation();
289+
HibernateGenerationStrategy generation();
234290

235291
/**
236292
* Filename or URL where the database create DDL file should be generated.
@@ -294,7 +350,48 @@ interface HibernateOrmConfigPersistenceUnitFlush {
294350
* @asciidoclet
295351
*/
296352
@WithDefault("auto")
297-
FlushMode mode();
353+
HibernateFlushMode mode();
298354
}
299355

356+
enum HibernateFlushMode {
357+
/**
358+
* The {@link Session} is only flushed when {@link Session#flush()}
359+
* is called explicitly. This mode is very efficient for read-only
360+
* transactions.
361+
*
362+
* @asciidoclet
363+
*/
364+
MANUAL,
365+
/**
366+
* The {@link Session} is flushed when {@link Transaction#commit()}
367+
* is called. It is never automatically flushed before query
368+
* execution.
369+
*
370+
* @see FlushModeType#COMMIT
371+
* @asciidoclet
372+
*/
373+
COMMIT,
374+
/**
375+
* The {@link Session} is flushed when {@link Transaction#commit()}
376+
* is called, and is sometimes flushed before query execution in
377+
* order to ensure that queries never return stale state. This is
378+
* the default flush mode.
379+
*
380+
* @see FlushModeType#AUTO
381+
* @asciidoclet
382+
*/
383+
AUTO,
384+
/**
385+
* The {@link Session} is flushed when {@link Transaction#commit()}
386+
* is called and before every query. This is usually unnecessary and
387+
* inefficient.
388+
*
389+
* @asciidoclet
390+
*/
391+
ALWAYS;
392+
393+
public FlushMode getHibernateFlushMode() {
394+
return FlushMode.valueOf(name());
395+
}
396+
}
300397
}

0 commit comments

Comments
 (0)