From fd961cebb1043fbc2db57a73b06e80e684a2260b Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 15 Aug 2023 13:38:31 -0500 Subject: [PATCH] HHH-17082 - Improve documentation of configuration settings https://hibernate.atlassian.net/browse/HHH-17082 --- documentation/documentation.gradle | 159 +- .../main/asciidoc/userguide/Bibliography.adoc | 3 +- .../userguide/ConfigPropertyList.adoc | 7 - .../userguide/Hibernate_User_Guide.adoc | 12 +- .../userguide/appendices/Annotations.adoc | 1464 -------- .../userguide/appendices/BestPractices.adoc | 5 - .../userguide/appendices/Configurations.adoc | 1185 ------- .../appendices/LegacyBasicTypeResolution.adoc | 1 + .../appendices/Legacy_DomainModel.adoc | 49 - .../appendices/Legacy_Native_Queries.adoc | 1 + .../appendices/SettingsReference.adoc | 27 + .../chapters/bootstrap/Bootstrap.adoc | 2 +- .../userguide/chapters/events/Events.adoc | 2 +- .../chapters/jdbc/Database_Access.adoc | 2 +- .../userguide/chapters/jndi/JNDI.adoc | 4 +- .../userguide/chapters/schema/Schema.adoc | 2 +- .../chapters/transactions/Transactions.adoc | 2 +- .../src/{ => main}/javadoc/overview.html | 2 +- .../src/{ => main}/javadoc/stylesheet.css | 0 documentation/status.md | 83 - gradle/javadoc.gradle | 20 +- .../c3p0/internal/C3P0ConnectionProvider.java | 55 +- .../org/hibernate/annotations/BatchSize.java | 2 + .../internal/BytecodeProviderInitiator.java | 2 +- .../bytebuddy/BytecodeProviderImpl.java | 2 +- .../internal/none/BytecodeProviderImpl.java | 1 - .../org/hibernate/cfg/AvailableSettings.java | 3136 +---------------- .../java/org/hibernate/cfg/BatchSettings.java | 73 + .../org/hibernate/cfg/BytecodeSettings.java | 46 + .../java/org/hibernate/cfg/C3p0Settings.java | 48 + .../java/org/hibernate/cfg/CacheSettings.java | 241 ++ .../hibernate/cfg/EnvironmentSettings.java | 56 + .../java/org/hibernate/cfg/FetchSettings.java | 62 + .../java/org/hibernate/cfg/JdbcSettings.java | 611 ++++ .../hibernate/cfg/JpaComplianceSettings.java | 217 ++ .../hibernate/cfg/ManagedBeanSettings.java | 105 + .../org/hibernate/cfg/MappingSettings.java | 572 +++ .../hibernate/cfg/MultiTenancySettings.java | 47 + .../hibernate/cfg/PersistenceSettings.java | 185 + .../org/hibernate/cfg/ProxoolSettings.java | 42 + .../java/org/hibernate/cfg/QuerySettings.java | 225 ++ .../hibernate/cfg/SchemaToolingSettings.java | 468 +++ .../hibernate/cfg/SessionEventSettings.java | 80 + .../org/hibernate/cfg/StatisticsSettings.java | 46 + .../hibernate/cfg/TransactionSettings.java | 181 + .../org/hibernate/cfg/ValidationSettings.java | 111 + .../batch/internal/BatchBuilderInitiator.java | 14 +- .../engine/jdbc/batch/spi/BatchBuilder.java | 2 +- .../internal/ConnectionProviderInitiator.java | 58 +- ...asedMultiTenantConnectionProviderImpl.java | 10 +- .../internal/log/ConnectionPoolingLogger.java | 4 +- .../EntityManagerFactoryBuilderImpl.java | 13 +- .../stat/internal/StatisticsInitiator.java | 8 +- .../insertordering/InsertOrderingTest.java | 7 +- .../batch/FailingAddToBatchTest.java | 7 +- .../batch/JtaWithFailingBatchTest.java | 4 +- .../batch/JtaWithStatementsBatchTest.java | 4 +- .../internal/HikariConfigurationUtil.java | 52 +- .../internal/ProxoolConnectionProvider.java | 19 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 63375 bytes .../gradle/wrapper/gradle-wrapper.properties | 4 +- local-build-plugins/gradlew | 293 +- local-build-plugins/gradlew.bat | 15 +- .../orm/properties/AsciiDocWriter.java | 87 +- .../orm/properties/SettingDescriptor.java | 131 +- .../SettingDescriptorComparator.java | 56 + .../orm/properties/SettingWorkingDetails.java | 140 + .../orm/properties/SettingsDocExtension.java | 12 +- .../properties/SettingsDocGenerationTask.java | 18 +- .../orm/properties/SettingsDocSection.java | 115 +- .../SettingsDocumentationPlugin.java | 1 - .../org/hibernate/orm/properties/Utils.java | 14 + .../jdk11/DomToAsciidocConverter.java | 176 + .../properties/jdk11/SettingsCollector.java | 359 ++ .../JavadocToAsciidocConverter.java} | 217 +- .../properties/jdk17/SettingsCollector.java | 270 ++ .../orm/toolchains/JavaModulePlugin.java | 35 +- 77 files changed, 5324 insertions(+), 6467 deletions(-) delete mode 100644 documentation/src/main/asciidoc/userguide/ConfigPropertyList.adoc delete mode 100644 documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc delete mode 100644 documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc delete mode 100644 documentation/src/main/asciidoc/userguide/appendices/Legacy_DomainModel.adoc create mode 100644 documentation/src/main/asciidoc/userguide/appendices/SettingsReference.adoc rename documentation/src/{ => main}/javadoc/overview.html (99%) rename documentation/src/{ => main}/javadoc/stylesheet.css (100%) delete mode 100644 documentation/status.md create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/BatchSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/BytecodeSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/C3p0Settings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/CacheSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/EnvironmentSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/FetchSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/JpaComplianceSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/ManagedBeanSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/MappingSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/MultiTenancySettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/ProxoolSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/SchemaToolingSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/SessionEventSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/StatisticsSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/TransactionSettings.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cfg/ValidationSettings.java create mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptorComparator.java create mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingWorkingDetails.java create mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/DomToAsciidocConverter.java create mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/SettingsCollector.java rename local-build-plugins/src/main/java/org/hibernate/orm/properties/{SettingsCollector.java => jdk17/JavadocToAsciidocConverter.java} (54%) create mode 100644 local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk17/SettingsCollector.java diff --git a/documentation/documentation.gradle b/documentation/documentation.gradle index 65b107f446..c87e3243a5 100644 --- a/documentation/documentation.gradle +++ b/documentation/documentation.gradle @@ -200,28 +200,34 @@ def aggregateJavadocsTask = tasks.register( "aggregateJavadocs", Javadoc ) { inputs.property "ormVersion", project.ormVersion destinationDir = mkdir( layout.buildDirectory.file( 'javadocs' ) ) - - source configurations.javadocSources - classpath += configurations.javadocClasspath + source = configurations.javadocSources + classpath = configurations.javadocClasspath // exclude any generated sources and internal packages exclude '**/generated-src/**' exclude '**/internal/**' include '**/*.java' + maxMemory = '512m' final int currentYear = new GregorianCalendar().get( Calendar.YEAR ) - // apply standard config - maxMemory = '512m' configure( options ) { - overview = 'src/javadoc/overview.html' - stylesheetFile = project.file( 'src/javadoc/stylesheet.css' ) - windowTitle = 'Hibernate JavaDocs' - docTitle = "Hibernate JavaDoc ($project.version)" + overview = 'src/main/javadoc/overview.html' + stylesheetFile = project.file( 'src/main/javadoc/stylesheet.css' ) + windowTitle = 'Hibernate Javadocs' + docTitle = "Hibernate Javadoc ($project.version)" bottom = "Copyright © 2001-$currentYear Red Hat, Inc. All Rights Reserved." use = true - options.encoding = 'UTF-8' + encoding = 'UTF-8' + + tags( + 'todo:X', + 'apiNote:a:API Note:', + 'implSpec:a:Implementation Specification:', + 'implNote:a:Implementation Note:', + 'settingDefault:f:Default Value:' + ) links = [ 'https://docs.oracle.com/en/java/javase/11/docs/api/', @@ -231,14 +237,14 @@ def aggregateJavadocsTask = tasks.register( "aggregateJavadocs", Javadoc ) { 'https://www.javadoc.io/doc/javax.cache/cache-api/1.0.0/' ] - options.addStringOption( 'Xdoclint:none', '-quiet' ) - - if ( jdkVersions.explicit ) { - options.setJFlags( - getProperty( 'toolchain.javadoc.jvmargs' ).toString(). - split( ' ' ).toList().findAll( { !it.isEmpty() } ) - ) - } + addStringOption( 'Xdoclint:none', '-quiet' ) +// +// if ( jdkVersions.explicit ) { +// setJFlags( +// getProperty( 'toolchain.javadoc.jvmargs' ).toString(). +// split( ' ' ).toList().findAll( { !it.isEmpty() } ) +// ) +// } } if ( jdkVersions.explicit ) { @@ -249,6 +255,18 @@ def aggregateJavadocsTask = tasks.register( "aggregateJavadocs", Javadoc ) { } } } + + doFirst { + def javaLanguageVersion = javadocTool.present + ? javadocTool.get().metadata.languageVersion + : JavaLanguageVersion.of( JavaVersion.current().name ) + + if ( javaLanguageVersion.asInt() > 11 ) { + println "`aggregateJavadocs` is being run with a JDK newer than version 11: \n" + + "\t* `stylesheet.css` will not be compatible\n" + + "\t* generating the User Guide settings fragment will not succeed" + } + } } asciidoctorj { @@ -480,30 +498,119 @@ def renderQueryLanguageGuidesTask = tasks.register( 'renderQueryLanguageGuides' // User Guide ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ settingsDocumentation { + anchorNameBase = "settings" sections { - core { - settingsClassName = "org.hibernate.cfg.AvailableSettings" - projectPath = ":hibernate-core" + compliance { + explicitPosition = 1 + summary = "Jakarta Persistence Compliance Settings" + description = "Settings which control various aspects of compliance with the Jakarta Persistence specification " + settingsClassName "org.hibernate.cfg.JpaComplianceSettings" + } + persistence { + explicitPosition = 2 + summary = "Persistence Unit Settings" + description = "Settings related to the creation and configuration of a persistence-unit - SessionFactory and EntityManagerFactory" + settingsClassName "org.hibernate.cfg.PersistenceSettings" + } + jdbc { + explicitPosition = 3 + summary = "JDBC Settings" + description = "Settings which control various aspects of how Hibernate interacts with JDBC" + settingsClassName "org.hibernate.cfg.JdbcSettings" + } + c3p0 { + explicitPosition = 4 + summary = "C3P0 Connection Pool Settings" + description = "Settings related to integrating with the C3P0 Connection pool" + settingsClassName "org.hibernate.cfg.C3p0Settings" + } + proxool { + explicitPosition = 5 + summary = "Proxool Connection Pool Settings" + description = "Settings related to integrating with the Proxool Connection pool" + settingsClassName "org.hibernate.cfg.ProxoolSettings" + } + mapping { + explicitPosition = 6 + summary = "Domain Mapping Settings" + description = "Settings which control how domain mappings are handled" + settingsClassName "org.hibernate.cfg.MappingSettings" + } + environment { + summary = "Runtime Environment Settings" + description = "Settings related to JNDI and ClassLoaders" + settingsClassName "org.hibernate.cfg.EnvironmentSettings" + } + schema { + summary = "Schema Tooling Settings" + description = "Settings which control the creation, dropping, update and validation of database schemas" + settingsClassName "org.hibernate.cfg.SchemaToolingSettings" + } + bytecode { + summary = "Bytecode Manipulation Settings" + description = "Settings which control Hibernate's BytecodeProvider used for bytecode manipulation" + settingsClassName "org.hibernate.cfg.BytecodeSettings" + } + cache { + summary = "Second-level Cache Settings" + description = "Settings which control Hibernate's second-level caching" + settingsClassName "org.hibernate.cfg.CacheSettings" + settingsClassName "org.hibernate.cache.jcache.ConfigSettings" + } + query { + summary = "Query Settings" + description = "Settings which control various parts of Hibernate's Query handling" + settingsClassName "org.hibernate.cfg.QuerySettings" + } + stats { + summary = "Statistics Settings" + description = "Settings which control the collection of statistics" + settingsClassName "org.hibernate.cfg.StatisticsSettings" + } + validation { + summary = "Jakarta Validation Integeration Settings" + description = "Settings used in the integration of Jakarta Validation" + settingsClassName "org.hibernate.cfg.ValidationSettings" } envers { - settingsClassName = "org.hibernate.envers.configuration.EnversSettings" - projectPath = ":hibernate-envers" + summary = "Audit/History Settings" + description = "Settings which control Hibernate's audit/history support (hibernate-envers)" + settingsClassName "org.hibernate.envers.configuration.EnversSettings" } - jcache { - settingsClassName = "org.hibernate.cache.jcache.ConfigSettings" - projectPath = ":hibernate-jcache" + spatial { + summary = "Hibernate Spatial Settings" + description = "Settings which control Hibernate's support for spatial data (hibernate-spatial)" + settingsClassName "org.hibernate.spatial.HibernateSpatialConfigurationSettings" + settingsClassName "org.hibernate.spatial.integration.SpatialService" + } + misc { + summary = "Miscellaneous Settings" + description = "Miscellaneous Settings" + settingsClassName "org.hibernate.cfg.AvailableSettings" } } } def generateSettingsDocTask = tasks.named( "generateSettingsDoc" ) { dependsOn aggregateJavadocsTask + + doFirst { + def javadoc = aggregateJavadocsTask.get() + def javaLanguageVersion = javadoc.javadocTool.present + ? javadoc.javadocTool.get().metadata.languageVersion + : JavaLanguageVersion.of( JavaVersion.current().name ) + + if ( javaLanguageVersion.asInt() > 11 ) { + println "`aggregateJavadocs` was run with a JDK newer than version 11; generating the settings User Guide fragment will not succeed" + } + } } def renderUserGuideHtmlTask = tasks.register( 'renderUserGuideHtml', AsciidoctorTask ) { task -> group = "Documentation" description = 'Renders the User Guides in HTML format using Asciidoctor.' inputs.property "hibernate-version", project.ormVersion + inputs.file( generateSettingsDocTask.get().outputFile ) dependsOn generateSettingsDocTask diff --git a/documentation/src/main/asciidoc/userguide/Bibliography.adoc b/documentation/src/main/asciidoc/userguide/Bibliography.adoc index 60170c18c2..b958d80eeb 100644 --- a/documentation/src/main/asciidoc/userguide/Bibliography.adoc +++ b/documentation/src/main/asciidoc/userguide/Bibliography.adoc @@ -1,6 +1,5 @@ -== References - [bibliography] +== References - [[[PoEAA]]] Martin Fowler. https://www.martinfowler.com/books/eaa.html[Patterns of Enterprise Application Architecture]. Addison-Wesley Professional. 2002. - [[[JPwH]]] Christian Bauer & Gavin King. https://www.manning.com/books/java-persistence-with-hibernate-second-edition[Java Persistence with Hibernate, Second Edition]. Manning Publications Co. 2015. diff --git a/documentation/src/main/asciidoc/userguide/ConfigPropertyList.adoc b/documentation/src/main/asciidoc/userguide/ConfigPropertyList.adoc deleted file mode 100644 index af75c6c2bd..0000000000 --- a/documentation/src/main/asciidoc/userguide/ConfigPropertyList.adoc +++ /dev/null @@ -1,7 +0,0 @@ -:documentation-project-dir: ../../../.. -:root-project-dir: {documentation-project-dir}/.. - -[[settings-ref]] -== List of all available configuration settings - -include::{documentation-project-dir}/target/asciidoc/fragments/config-settings.adoc[] \ No newline at end of file diff --git a/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc b/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc index 6e0b5d539e..63dae70c76 100644 --- a/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc +++ b/documentation/src/main/asciidoc/userguide/Hibernate_User_Guide.adoc @@ -39,17 +39,13 @@ include::chapters/beans/Beans.adoc[] include::chapters/portability/Portability.adoc[] include::chapters/statistics/Statistics.adoc[] include::chapters/tooling/Tooling.adoc[] - -include::appendices/Configurations.adoc[] -include::appendices/Annotations.adoc[] include::appendices/BestPractices.adoc[] -include::appendices/Legacy_Bootstrap.adoc[] -include::appendices/Legacy_DomainModel.adoc[] -include::appendices/LegacyBasicTypeResolution.adoc[] -include::appendices/Legacy_Native_Queries.adoc[] include::Credits.adoc[] -include::ConfigPropertyList.adoc[] +include::appendices/SettingsReference.adoc[] +include::appendices/LegacyBasicTypeResolution.adoc[] +include::appendices/Legacy_Native_Queries.adoc[] + include::Bibliography.adoc[] diff --git a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc b/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc deleted file mode 100644 index f122dfe993..0000000000 --- a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc +++ /dev/null @@ -1,1464 +0,0 @@ -[[annotations]] -== Mapping annotations - -[[annotations-jpa]] -=== Jakarta Persistence annotations - -[[annotations-jpa-access]] -==== `@Access` - -The {jpaJavadocUrlPrefix}Access.html[`@Access`] annotation is used to specify the access type of the associated entity class, mapped superclass, or embeddable class, or entity attribute. - -See the <> section for more info. - -[[annotations-jpa-associationoverride]] -==== `@AssociationOverride` - -The {jpaJavadocUrlPrefix}AssociationOverride.html[`@AssociationOverride`] annotation is used to override an association mapping (e.g. `@ManyToOne`, `@OneToOne`, `@OneToMany`, `@ManyToMany`) inherited from a mapped superclass or an embeddable. - -See the <> section for more info. - -[[annotations-jpa-associationoverrides]] -==== `@AssociationOverrides` - -The {jpaJavadocUrlPrefix}AssociationOverrides.html[`@AssociationOverrides`] is used to group several <> annotations. - -[[annotations-jpa-attributeoverride]] -==== `@AttributeOverride` - -The {jpaJavadocUrlPrefix}AttributeOverride.html[`@AttributeOverride`] annotation is used to override an attribute mapping inherited from a mapped superclass or an embeddable. - -See the <> section for more info. - -[[annotations-jpa-attributeoverrides]] -==== `@AttributeOverrides` - -The {jpaJavadocUrlPrefix}AttributeOverrides.html[`@AttributeOverrides`] is used to group several <> annotations. - -[[annotations-jpa-basic]] -==== `@Basic` - -The {jpaJavadocUrlPrefix}Basic.html[`@Basic`] annotation is used to map a basic attribute type to a database column. - -See the <> chapter for more info. - -[[annotations-jpa-cacheable]] -==== `@Cacheable` - -The {jpaJavadocUrlPrefix}Cacheable.html[`@Cacheable`] annotation is used to specify whether an entity should be stored in the second-level cache. - -If the `persistence.xml` `shared-cache-mode` XML attribute is set to `ENABLE_SELECTIVE`, then only the entities annotated with the `@Cacheable` are going to be stored in the second-level cache. - -If `shared-cache-mode` XML attribute value is `DISABLE_SELECTIVE`, then the entities marked with the `@Cacheable` annotation are not going to be stored in the second-level cache, while all the other entities are stored in the cache. - -See the <> chapter for more info. - -[[annotations-jpa-collectiontable]] -==== `@CollectionTable` - -The {jpaJavadocUrlPrefix}CollectionTable.html[`@CollectionTable`] annotation is used to specify the database table that stores the values of a basic or an embeddable type collection. - -See the <> section for more info. - -[[annotations-jpa-column]] -==== `@Column` - -The {jpaJavadocUrlPrefix}Column.html[`@Column`] annotation is used to specify the mapping between a basic entity attribute and the database table column. - -See the <> section for more info. - -[[annotations-jpa-columnresult]] -==== `@ColumnResult` - -The {jpaJavadocUrlPrefix}ColumnResult.html[`@ColumnResult`] annotation is used in conjunction with the <> or <> annotations to map a SQL column for a given SELECT query. - -See the <> section for more info. - -[[annotations-jpa-constructorresult]] -==== `@ConstructorResult` - -The {jpaJavadocUrlPrefix}ConstructorResult.html[`@ConstructorResult`] annotation is used in conjunction with the <> annotations to map columns of a given SELECT query to a certain object constructor. - -See the <> section for more info. - -[[annotations-jpa-convert]] -==== `@Convert` - -The {jpaJavadocUrlPrefix}Convert.html[`@Convert`] annotation is used to specify the {jpaJavadocUrlPrefix}AttributeConverter.html[`AttributeConverter`] implementation used to convert the currently annotated basic attribute. - -If the `AttributeConverter` uses {jpaJavadocUrlPrefix}Converter.html#autoApply--[`autoApply`], then all entity attributes with the same target type are going to be converted automatically. - -See the <> section for more info. - -[[annotations-jpa-converter]] -==== `@Converter` - -The {jpaJavadocUrlPrefix}Converter.html[`@Converter`] annotation is used to specify that the currently annotated {jpaJavadocUrlPrefix}AttributeConverter.html[`AttributeConverter`] implementation can be used as a Jakarta Persistence basic attribute converter. -specj -If the {jpaJavadocUrlPrefix}Converter.html#autoApply--[`autoApply`] attribute is set to `true`, then the Jakarta Persistence provider will automatically convert all basic attributes with the same Java type as defined by the current converter. - -See the <> section for more info. - -[[annotations-jpa-converts]] -==== `@Converts` - -The {jpaJavadocUrlPrefix}Converts.html[`@Converts`] annotation is used to group multiple <> annotations. - -See the <> section for more info. - -[[annotations-jpa-discriminatorcolumn]] -==== `@DiscriminatorColumn` - -The {jpaJavadocUrlPrefix}DiscriminatorColumn.html[`@DiscriminatorColumn`] annotation is used to specify the discriminator column name and the {jpaJavadocUrlPrefix}DiscriminatorColumn.html#discriminatorType--[discriminator type] for the `SINGLE_TABLE` and `JOINED` inheritance strategies. - -See the <> section for more info. - -[[annotations-jpa-discriminatorvalue]] -==== `@DiscriminatorValue` - -The {jpaJavadocUrlPrefix}DiscriminatorValue.html[`@DiscriminatorValue`] annotation is used to specify what value of the discriminator column is used for mapping the currently annotated entity. - -See the <> section for more info. - -[[annotations-jpa-elementcollection]] -==== `@ElementCollection` - -The {jpaJavadocUrlPrefix}ElementCollection.html[`@ElementCollection`] annotation is used to specify a collection of a basic or embeddable types. - -See the <> section for more info. - -[[annotations-jpa-embeddable]] -==== `@Embeddable` - -The {jpaJavadocUrlPrefix}Embeddable.html[`@Embeddable`] annotation is used to specify embeddable types. Like basic types, embeddable types do not have any identity, being managed by their owning entity. - -See the <> section for more info. - -[[annotations-jpa-embedded]] -==== `@Embedded` - -The {jpaJavadocUrlPrefix}Embedded.html[`@Embedded`] annotation is used to specify that a given entity attribute represents an embeddable type. - -See the <> section for more info. - -[[annotations-jpa-embeddedid]] -==== `@EmbeddedId` - -The {jpaJavadocUrlPrefix}EmbeddedId.html[`@EmbeddedId`] annotation is used to specify the entity identifier is an embeddable type. - -See the <> section for more info. - -[[annotations-jpa-entity]] -==== `@Entity` - -The {jpaJavadocUrlPrefix}Entity.html[`@Entity`] annotation is used to specify that the currently annotated class represents an entity type. -Unlike basic and embeddable types, entity types have an identity and their state is managed by the underlying Persistence Context. - -See the <> section for more info. - -[[annotations-jpa-entitylisteners]] -==== `@EntityListeners` - -The {jpaJavadocUrlPrefix}EntityListeners.html[`@EntityListeners`] annotation is used to specify an array of callback listener classes that are used by the currently annotated entity. - -See the <> section for more info. - -[[annotations-jpa-entityresult]] -==== `@EntityResult` - -The {jpaJavadocUrlPrefix}EntityResult.html[`@EntityResult`] annotation is used with the <> annotation to map the selected columns to an entity. - -See the <> section for more info. - -[[annotations-jpa-enumerated]] -==== `@Enumerated` - -The {jpaJavadocUrlPrefix}Enumerated.html[`@Enumerated`] annotation is used to specify that an entity attribute represents an enumerated type. - -See the <> section for more info. - -[[annotations-jpa-excludedefaultlisteners]] -==== `@ExcludeDefaultListeners` - -The {jpaJavadocUrlPrefix}ExcludeDefaultListeners.html[`@ExcludeDefaultListeners`] annotation is used to specify that the currently annotated entity skips the invocation of any default listener. - -See the <> section for more info. - -[[annotations-jpa-excludesuperclasslisteners]] -==== `@ExcludeSuperclassListeners` - -The {jpaJavadocUrlPrefix}ExcludeSuperclassListeners.html[`@ExcludeSuperclassListeners`] annotation is used to specify that the currently annotated entity skips the invocation of listeners declared by its superclass. - -See the <> section for more info. - -[[annotations-jpa-fieldresult]] -==== `@FieldResult` - -The {jpaJavadocUrlPrefix}FieldResult.html[`@FieldResult`] annotation is used with the <> annotation to map the selected columns to the fields of some specific entity. - -See the <> section for more info. - -[[annotations-jpa-foreignkey]] -==== `@ForeignKey` - -The {jpaJavadocUrlPrefix}ForeignKey.html[`@ForeignKey`] annotation is used to specify the associated foreign key of a <> mapping. -The `@ForeignKey` annotation is only used if the automated schema generation tool is enabled, in which case, it allows you to customize the underlying foreign key definition. - -See the <> section for more info. - -[[annotations-jpa-generatedvalue]] -==== `@GeneratedValue` - -The {jpaJavadocUrlPrefix}GeneratedValue.html[`@GeneratedValue`] annotation specifies that the entity identifier value is automatically generated using an identity column, a database sequence, or a table generator. -Hibernate supports the `@GeneratedValue` mapping even for `UUID` identifiers. - -See the <> section for more info. - -[[annotations-jpa-id]] -==== `@Id` - -The {jpaJavadocUrlPrefix}Id.html[`@Id`] annotation specifies the entity identifier. -An entity must always have an identifier attribute which is used when loading the entity in a given Persistence Context. - -See the <> section for more info. - -[[annotations-jpa-idclass]] -==== `@IdClass` - -The {jpaJavadocUrlPrefix}IdClass.html[`@IdClass`] annotation is used if the current entity defined a composite identifier. -A separate class encapsulates all the identifier attributes, which are mirrored by the current entity mapping. - -See the <> section for more info. - -[[annotations-jpa-index]] -==== `@Index` - -The {jpaJavadocUrlPrefix}Index.html[`@Index`] annotation is used by the automated schema generation tool to create a database index. - -See the <> chapter for more info. - -[[annotations-jpa-inheritance]] -==== `@Inheritance` - -The {jpaJavadocUrlPrefix}Inheritance.html[`@Inheritance`] annotation is used to specify the inheritance strategy of a given entity class hierarchy. - -See the <> section for more info. - -[[annotations-jpa-joincolumn]] -==== `@JoinColumn` - -The {jpaJavadocUrlPrefix}JoinColumn.html[`@JoinColumn`] annotation is used to specify the FOREIGN KEY column used when joining an entity association or an embeddable collection. - -See the <> section for more info. - -[[annotations-jpa-joincolumns]] -==== `@JoinColumns` - -The {jpaJavadocUrlPrefix}JoinColumns.html[`@JoinColumns`] annotation is used to group multiple <> annotations, which are used when mapping entity association or an embeddable collection using a composite identifier. - -[[annotations-jpa-jointable]] -==== `@JoinTable` - -The {jpaJavadocUrlPrefix}JoinTable.html[`@JoinTable`] annotation is used to specify the link table between two other database tables. - -See the <> section for more info. - -[[annotations-jpa-lob]] -==== `@Lob` - -The {jpaJavadocUrlPrefix}Lob.html[`@Lob`] annotation is used to specify that the currently annotated entity attribute represents a large object type. - -See the <> section for more info. - -[[annotations-jpa-manytomany]] -==== `@ManyToMany` - -The {jpaJavadocUrlPrefix}ManyToMany.html[`@ManyToMany`] annotation is used to specify a many-to-many database relationship. - -See the <> section for more info. - -[[annotations-jpa-manytoone]] -==== `@ManyToOne` - -The {jpaJavadocUrlPrefix}ManyToOne.html[`@ManyToOne`] annotation is used to specify a many-to-one database relationship. - -See the <> section for more info. - -[[annotations-jpa-mapkey]] -==== `@MapKey` - -The {jpaJavadocUrlPrefix}MapKey.html[`@MapKey`] annotation is used to specify the key of a `java.util.Map` association for which the key type is either the primary key or an attribute of the entity which represents the value of the map. - -See the <> section for more info. - -[[annotations-jpa-mapkeyclass]] -==== `@MapKeyClass` - -The {jpaJavadocUrlPrefix}MapKeyClass.html[`@MapKeyClass`] annotation is used to specify the type of the map key of a `java.util.Map` associations. - -See the <> section for more info. - -[[annotations-jpa-mapkeycolumn]] -==== `@MapKeyColumn` - -The {jpaJavadocUrlPrefix}MapKeyColumn.html[`@MapKeyColumn`] annotation is used to specify the database column which stores the key of a `java.util.Map` association for which the map key is a basic type. - -See the <> for an example of `@MapKeyColumn` annotation usage. - -[[annotations-jpa-mapkeyenumerated]] -==== `@MapKeyEnumerated` - -The {jpaJavadocUrlPrefix}MapKeyEnumerated.html[`@MapKeyEnumerated`] annotation is used to specify that the key of `java.util.Map` association is a Java Enum. - -See the <> section for more info. - -[[annotations-jpa-mapkeyjoincolumn]] -==== `@MapKeyJoinColumn` - -The {jpaJavadocUrlPrefix}MapKeyJoinColumn.html[`@MapKeyJoinColumn`] annotation is used to specify that the key of `java.util.Map` association is an entity association. -The map key column is a FOREIGN KEY in a link table that also joins the `Map` owner's table with the table where the `Map` value resides. - -See the <> section for more info. - -[[annotations-jpa-mapkeyjoincolumns]] -==== `@MapKeyJoinColumns` - -The {jpaJavadocUrlPrefix}MapKeyJoinColumns.html[`@MapKeyJoinColumns`] annotation is used to group several <> mappings when the `java.util.Map` association key uses a composite identifier. - -[[annotations-jpa-mapkeytemporal]] -==== `@MapKeyTemporal` - -The {jpaJavadocUrlPrefix}MapKeyTemporal.html[`@MapKeyTemporal`] annotation is used to specify that the key of `java.util.Map` association is a {jpaJavadocUrlPrefix}TemporalType.html[`@TemporalType`] (e.g. `DATE`, `TIME`, `TIMESTAMP`). - -See the <> section for more info. - -[[annotations-jpa-mappedsuperclass]] -==== `@MappedSuperclass` - -The {jpaJavadocUrlPrefix}MappedSuperclass.html[`@MappedSuperclass`] annotation is used to specify that the currently annotated type attributes are inherited by any subclass entity. - -See the <> section for more info. - -[[annotations-jpa-mapsid]] -==== `@MapsId` - -The {jpaJavadocUrlPrefix}MapsId.html[`@MapsId`] annotation is used to specify that the entity identifier is mapped by the currently annotated `@ManyToOne` or `@OneToOne` association. - -See the <> section for more info. - -[[annotations-jpa-namedattributenode]] -==== `@NamedAttributeNode` - -The {jpaJavadocUrlPrefix}NamedAttributeNode.html[`@NamedAttributeNode`] annotation is used to specify each individual attribute node that needs to be fetched by an Entity Graph. - -See the <> section for more info. - -[[annotations-jpa-namedentitygraph]] -==== `@NamedEntityGraph` - -The {jpaJavadocUrlPrefix}NamedEntityGraph.html[`@NamedEntityGraph`] annotation is used to specify an Entity Graph that can be used by an entity query to override the default fetch plan. - -See the <> section for more info. - -[[annotations-jpa-namedentitygraphs]] -==== `@NamedEntityGraphs` - -The {jpaJavadocUrlPrefix}NamedEntityGraphs.html[`@NamedEntityGraphs`] annotation is used to group multiple <> annotations. - -[[annotations-jpa-namednativequeries]] -==== `@NamedNativeQueries` - -The {jpaJavadocUrlPrefix}NamedNativeQueries.html[`@NamedNativeQueries`] annotation is used to group multiple <> annotations. - -See the <> section for more info. - -[[annotations-jpa-namednativequery]] -==== `@NamedNativeQuery` - -The {jpaJavadocUrlPrefix}NamedNativeQuery.html[`@NamedNativeQuery`] annotation is used to specify a native SQL query that can be retrieved later by its name. - -See the <> section for more info. - -[[annotations-jpa-namedqueries]] -==== `@NamedQueries` - -The {jpaJavadocUrlPrefix}NamedQueries.html[`@NamedQueries`] annotation is used to group multiple <> annotations. - -[[annotations-jpa-namedquery]] -==== `@NamedQuery` - -The {jpaJavadocUrlPrefix}NamedQuery.html[`@NamedQuery`] annotation is used to specify a JPQL query that can be retrieved later by its name. - -See the <> section for more info. - -[[annotations-jpa-namedstoredprocedurequeries]] -==== `@NamedStoredProcedureQueries` - -The {jpaJavadocUrlPrefix}NamedStoredProcedureQueries.html[`@NamedStoredProcedureQueries`] annotation is used to group multiple <> annotations. - -[[annotations-jpa-namedstoredprocedurequery]] -==== `@NamedStoredProcedureQuery` - -The {jpaJavadocUrlPrefix}NamedStoredProcedureQuery.html[`@NamedStoredProcedureQuery`] annotation is used to specify a stored procedure query that can be retrieved later by its name. - -See the <> section for more info. - -[[annotations-jpa-namedsubgraph]] -==== `@NamedSubgraph` - -The {jpaJavadocUrlPrefix}NamedSubgraph.html[`@NamedSubgraph`] annotation used to specify a subgraph in an Entity Graph. - -See the <> section for more info. - -[[annotations-jpa-onetomany]] -==== `@OneToMany` - -The {jpaJavadocUrlPrefix}OneToMany.html[`@OneToMany`] annotation is used to specify a one-to-many database relationship. - -See the <> section for more info. - -[[annotations-jpa-onetoone]] -==== `@OneToOne` - -The {jpaJavadocUrlPrefix}OneToOne.html[`@OneToOne`] annotation is used to specify a one-to-one database relationship. - -See the <> section for more info. - -[[annotations-jpa-orderby]] -==== `@OrderBy` - -The {jpaJavadocUrlPrefix}OrderBy.html[`@OrderBy`] annotation is used to specify the entity attributes used for sorting when fetching the currently annotated collection. - -See the <> section for more info. - -[[annotations-jpa-ordercolumn]] -==== `@OrderColumn` - -The {jpaJavadocUrlPrefix}OrderColumn.html[`@OrderColumn`] annotation is used to specify that the current annotation collection order should be materialized in the database. - -See the <> section for more info. - -[[annotations-jpa-persistencecontext]] -==== `@PersistenceContext` - -The {jpaJavadocUrlPrefix}PersistenceContext.html[`@PersistenceContext`] annotation is used to specify the `EntityManager` that needs to be injected as a dependency. - -See the <> section for more info. - -[[annotations-jpa-persistencecontexts]] -==== `@PersistenceContexts` - -The {jpaJavadocUrlPrefix}PersistenceContexts.html[`@PersistenceContexts`] annotation is used to group multiple <> annotations. - -[[annotations-jpa-persistenceproperty]] -==== `@PersistenceProperty` - -The {jpaJavadocUrlPrefix}PersistenceProperty.html[`@PersistenceProperty`] annotation is used by the <> annotation to declare Jakarta Persistence provider properties that are passed to the underlying container when the `EntityManager` instance is created. - -See the <> section for more info. - -[[annotations-jpa-persistenceunit]] -==== `@PersistenceUnit` - -The {jpaJavadocUrlPrefix}PersistenceUnit.html[`@PersistenceUnit`] annotation is used to specify the `EntityManagerFactory` that needs to be injected as a dependency. - -See the <> section for more info. - -[[annotations-jpa-persistenceunits]] -==== `@PersistenceUnits` - -The {jpaJavadocUrlPrefix}PersistenceUnits.html[`@PersistenceUnits`] annotation is used to group multiple <> annotations. - -[[annotations-jpa-postload]] -==== `@PostLoad` - -The {jpaJavadocUrlPrefix}PostLoad.html[`@PostLoad`] annotation is used to specify a callback method that fires after an entity is loaded. - -See the <> section for more info. - -[[annotations-jpa-postpersist]] -==== `@PostPersist` - -The {jpaJavadocUrlPrefix}PostPersist.html[`@PostPersist`] annotation is used to specify a callback method that fires after an entity is persisted. - -See the <> section for more info. - -[[annotations-jpa-postremove]] -==== `@PostRemove` - -The {jpaJavadocUrlPrefix}PostRemove.html[`@PostRemove`] annotation is used to specify a callback method that fires after an entity is removed. - -See the <> section for more info. - -[[annotations-jpa-postupdate]] -==== `@PostUpdate` - -The {jpaJavadocUrlPrefix}PostUpdate.html[`@PostUpdate`] annotation is used to specify a callback method that fires after an entity is updated. - -See the <> section for more info. - -[[annotations-jpa-prepersist]] -==== `@PrePersist` - -The {jpaJavadocUrlPrefix}PrePersist.html[`@PrePersist`] annotation is used to specify a callback method that fires before an entity is persisted. - -See the <> section for more info. - -[[annotations-jpa-preremove]] -==== `@PreRemove` - -The {jpaJavadocUrlPrefix}PreRemove.html[`@PreRemove`] annotation is used to specify a callback method that fires before an entity is removed. - -See the <> section for more info. - -[[annotations-jpa-preupdate]] -==== `@PreUpdate` - -The {jpaJavadocUrlPrefix}PreUpdate.html[`@PreUpdate`] annotation is used to specify a callback method that fires before an entity is updated. - -See the <> section for more info. - -[[annotations-jpa-primarykeyjoincolumn]] -==== `@PrimaryKeyJoinColumn` - -The {jpaJavadocUrlPrefix}PrimaryKeyJoinColumn.html[`@PrimaryKeyJoinColumn`] annotation is used to specify that the primary key column of the currently annotated entity is also a foreign key to some other entity -(e.g. a base class table in a `JOINED` inheritance strategy, the primary table in a secondary table mapping, or the parent table in a `@OneToOne` relationship). - -See the <> section for more info. - -[[annotations-jpa-primarykeyjoincolumns]] -==== `@PrimaryKeyJoinColumns` - -The {jpaJavadocUrlPrefix}PrimaryKeyJoinColumns.html[`@PrimaryKeyJoinColumns`] annotation is used to group multiple <> annotations. - -[[annotations-jpa-queryhint]] -==== `@QueryHint` - -The {jpaJavadocUrlPrefix}QueryHint.html[`@QueryHint`] annotation is used to specify a Jakarta Persistence provider hint used by a `@NamedQuery` or a `@NamedNativeQuery` annotation. - -See the <> section for more info. - -[[annotations-jpa-secondarytable]] -==== `@SecondaryTable` - -The {jpaJavadocUrlPrefix}SecondaryTable.html[`@SecondaryTable`] annotation is used to specify a secondary table for the currently annotated entity. - -See the <> section for more info. - -[[annotations-jpa-secondarytables]] -==== `@SecondaryTables` - -The {jpaJavadocUrlPrefix}SecondaryTables.html[`@SecondaryTables`] annotation is used to group multiple <> annotations. - -[[annotations-jpa-sequencegenerator]] -==== `@SequenceGenerator` - -The {jpaJavadocUrlPrefix}SequenceGenerator.html[`@SequenceGenerator`] annotation is used to specify the database sequence used by the identifier generator of the currently annotated entity. - -See the <> section for more info. - -[[annotations-jpa-sqlresultsetmapping]] -==== `@SqlResultSetMapping` - -The {jpaJavadocUrlPrefix}SqlResultSetMapping.html[`@SqlResultSetMapping`] annotation is used to specify the `ResultSet` mapping of a native SQL query or stored procedure. - -See the <> section for more info. - -[[annotations-jpa-sqlresultsetmappings]] -==== `@SqlResultSetMappings` - -The {jpaJavadocUrlPrefix}SqlResultSetMappings.html[`@SqlResultSetMappings`] annotation is group multiple <> annotations. - -[[annotations-jpa-storedprocedureparameter]] -==== `@StoredProcedureParameter` - -The {jpaJavadocUrlPrefix}StoredProcedureParameter.html[`@StoredProcedureParameter`] annotation is used to specify a parameter of a <>. - -See the <> section for more info. - -[[annotations-jpa-table]] -==== `@Table` - -The {jpaJavadocUrlPrefix}Table.html[`@Table`] annotation is used to specify the primary table of the currently annotated entity. - -See the <> section for more info. - -[[annotations-jpa-tablegenerator]] -==== `@TableGenerator` - -The {jpaJavadocUrlPrefix}TableGenerator.html[`@TableGenerator`] annotation is used to specify the database table used by the identity generator of the currently annotated entity. - -See the <> section for more info. - -[[annotations-jpa-temporal]] -==== `@Temporal` - -The {jpaJavadocUrlPrefix}Temporal.html[`@Temporal`] annotation is used to specify the `TemporalType` of the currently annotated `java.util.Date` or `java.util.Calendar` entity attribute. - -See the <> chapter for more info. - -[[annotations-jpa-transient]] -==== `@Transient` - -The {jpaJavadocUrlPrefix}Transient.html[`@Transient`] annotation is used to specify that a given entity attribute should not be persisted. - -See the <> section for more info. - -[[annotations-jpa-uniqueconstraint]] -==== `@UniqueConstraint` - -The {jpaJavadocUrlPrefix}UniqueConstraint.html[`@UniqueConstraint`] annotation is used to specify a unique constraint to be included by the automated schema generator for the primary or secondary table associated with the currently annotated entity. - -See the <> chapter for more info. - -[[annotations-jpa-version]] -==== `@Version` - -The {jpaJavadocUrlPrefix}Version.html[`@Version`] annotation is used to specify the version attribute used for optimistic locking. - -See the <> section for more info. - -[[annotations-hibernate]] -=== Hibernate annotations - -[[annotations-hibernate-any]] -==== `@Any` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Any.html[`@Any`] annotation is -used to define the *any-to-one* association which can point to one of several entity types. - -See the <> section for more info. - -[[annotations-hibernate-anydiscriminator]] -==== `@AnyDiscriminator` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AnyDiscriminator.html[`@AnyDiscriminator`] -annotation is used to provide details about the discriminator portion of an `@Any` or `@ManyToAny` mapping. - -See the <> section for more info. - -[[annotations-hibernate-anydiscriminatorvalue]] -==== `@AnyDiscriminatorValue` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AnyDiscriminatorValue.html[`@AnyDiscriminatorValue`] -annotation maps a single discriminator value to its corresponding entity - -See the <> section for more info. - -[[annotations-hibernate-anydiscriminatorvalues]] -==== `@AnyDiscriminatorValues` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AnyDiscriminatorValues.html[`@AnyDiscriminatorValues`] -annotation groups multiple <> annotations. - -See the <> section for more info. - -[[annotations-hibernate-anykeyjavaclass]] -==== `@AnyKeyJavaClass` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AnyKeyJavaClass.html[`@AnyKeyJavaClass`] -annotation specifies the Java Class to use for the foreign-key of an ANY mapping - -See the <> section for more info. - -[[annotations-hibernate-anykeyjavatype]] -==== `@AnyKeyJavaType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AnyKeyJavaType.html[`@AnyKeyJavaType`] -annotation specifies a specific JavaType descriptor to use for the foreign-key of an ANY mapping - -See the <> section for more info. - - -[[annotations-hibernate-anykeyjdbctype]] -==== `@AnyKeyJdbcType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AnyKeyJdbcType.html[`@AnyKeyJdbcType`] -annotation specifies a specific JdbcType descriptor to use for the foreign-key of an ANY mapping - -See the <> section for more info. - -[[annotations-hibernate-anykeyjdbctypecode]] -==== `@AnyKeyJdbcTypeCode` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AnyKeyJdbcTypeCode.html[`@AnyKeyJdbcTypeCode`] -annotation specifies a "type code" indicating which JdbcType descriptor to use for the foreign-key of an ANY mapping - -See the <> section for more info. - - -[[annotations-hibernate-attributeaccessor]] -==== `@AttributeAccessor` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AttributeAccessor.html[`@AttributeAccessor`] annotation is used to specify a custom https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/property/access/spi/PropertyAccessStrategy.html[`PropertyAccessStrategy`]. - -Should only be used to name a custom `PropertyAccessStrategy`. -For property/field access type, the Jakarta Persistence <> annotation should be preferred. - -However, if this annotation is used with either value="property" or value="field", it will act just as the corresponding usage of the Jakarta Persistence <> annotation. - - -[[annotations-hibernate-attributebindertype]] -==== `@AttributeBinderType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/AttributeBinderType.html[`@AttributeBinderType`] -annotation is a meta-annotation used to annotate a custom annotation type used to drive customized model binding. - -See <>. - - -[[annotations-hibernate-batchsize]] -==== `@BatchSize` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/BatchSize.html[`@BatchSize`] annotation is used to specify the size for batch loading the entries of a lazy collection. - -See the <> section for more info. - -[[annotations-hibernate-cache]] -==== `@Cache` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Cache.html[`@Cache`] annotation is used to specify the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CacheConcurrencyStrategy.html[`CacheConcurrencyStrategy`] of a root entity or a collection. - -See the <> chapter for more info. - -[[annotations-hibernate-cascade]] -==== `@Cascade` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Cascade.html[`@Cascade`] annotation is used to apply the Hibernate specific https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CascadeType.html[`CascadeType`] strategies (e.g. `CascadeType.LOCK`, `CascadeType.SAVE_UPDATE`, `CascadeType.REPLICATE`) on a given association. - -For Jakarta Persistence cascading, prefer using the {jpaJavadocUrlPrefix}CascadeType.html[`jakarta.persistence.CascadeType`] instead. - -When combining both Jakarta Persistence and Hibernate `CascadeType` strategies, Hibernate will merge both sets of cascades. - -See the <> chapter for more info. - -[[annotations-hibernate-check]] -==== `@Check` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Check.html[`@Check`] annotation is used to specify an arbitrary SQL CHECK constraint which can be defined at the class level. - -See the <> chapter for more info. - -[[annotations-hibernate-collectionid]] -==== `@CollectionId` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CollectionId.html[`@CollectionId`] annotation is used to specify an identifier column for an idbag collection. - -You might want to use the Jakarta Persistence <> instead. - -[[annotations-hibernate-collectiontype]] -==== `@CollectionType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CollectionType.html[`@CollectionType`] annotation is used to specify a custom collection type. - -The collection can also name a <>, which defines the Hibernate Type of the collection elements. - -See the <> chapter for more info. - -[[annotations-hibernate-columndefault]] -==== `@ColumnDefault` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ColumnDefault.html[`@ColumnDefault`] annotation is used to specify the `DEFAULT` DDL value to apply when using the automated schema generator. - -The same behavior can be achieved using the `definition` attribute of the Jakarta Persistence <> annotation. - -See the <> chapter for more info. - -[[annotations-hibernate-columns]] -==== `@Columns` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Columns.html[`@Columns`] annotation is used to group multiple Jakarta Persistence <> annotations. - -See the <> section for more info. - -[[annotations-hibernate-columntransformer]] -==== `@ColumnTransformer` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ColumnTransformer.html[`@ColumnTransformer`] annotation is used to customize how a given column value is read from or written into the database. - -See the <> section for more info. - -[[annotations-hibernate-columntransformers]] -==== `@ColumnTransformers` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ColumnTransformers.html[`@ColumnTransformers`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-creationtimestamp]] -==== `@CreationTimestamp` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CreationTimestamp.html[`@CreationTimestamp`] annotation is used to specify that the currently annotated temporal type must be initialized with the current JVM timestamp value. - -The supported property types are: - -- `java.util.Date` -- `java.util.Calendar` -- `java.sql.Date` -- `java.sql.Time` -- `java.sql.Timestamp` -- `java.time.Instant` -- `java.time.LocalDate` -- `java.time.LocalDateTime` -- `java.time.LocalTime` -- `java.time.MonthDay` -- `java.time.OffsetDateTime` -- `java.time.OffsetTime` -- `java.time.Year` -- `java.time.YearMonth` -- `java.time.ZonedDateTime` - -See the <> section for more info. - -[[annotations-hibernate-compositetype]] -==== `@CompositeType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CompositeType.html[`@CompositeType`] annotation is used to supply an implementation of the `org.hibernate.usertype.CompositeUserType` contract for the annotated attribute mapping. - -See the <> section for more info. - -[[annotations-hibernate-compositetyperegistration]] -==== `@CompositeTypeRegistration` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CompositeTypeRegistration.html[`@CompositeTypeRegistration`] annotation provides a way to register an implementation of the `org.hibernate.usertype.CompositeUserType` contract for all references to a particular `@Embeddable`. - -See the <> section for more info. - -[[annotations-hibernate-compositetyperegistrations]] -==== `@CompositeTypeRegistrations` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CompositeTypeRegistrations.html[`@CompositeTypeRegistrations`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-discriminatorformula]] -==== `@DiscriminatorFormula` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/DiscriminatorFormula.html[`@DiscriminatorFormula`] annotation is used to specify a Hibernate <> to resolve the inheritance discriminator value. - -See the <> section for more info. - -[[annotations-hibernate-discriminatoroptions]] -==== `@DiscriminatorOptions` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/DiscriminatorOptions.html[`@DiscriminatorOptions`] annotation is used to provide the `force` and `insert` Discriminator properties. - -See the <> section for more info. - -[[annotations-hibernate-dynamicinsert]] -==== `@DynamicInsert` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/DynamicInsert.html[`@DynamicInsert`] annotation is used to specify that the `INSERT` SQL statement should be generated whenever an entity is to be persisted. - -By default, Hibernate uses a cached `INSERT` statement that sets all table columns. -When the entity is annotated with the `@DynamicInsert` annotation, the `PreparedStatement` is going to include only the non-null columns. - -See the <> section for more info on how `@DynamicInsert` works. - -[[annotations-hibernate-dynamicupdate]] -==== `@DynamicUpdate` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/DynamicUpdate.html[`@DynamicUpdate`] annotation is used to specify that the `UPDATE` SQL statement should be generated whenever an entity is modified. - -By default, Hibernate uses a cached `UPDATE` statement that sets all table columns. -When the entity is annotated with the `@DynamicUpdate` annotation, the `PreparedStatement` is going to include only the columns whose values have been changed. - -See the <> section for more info. - -[NOTE] -==== -For reattachment of detached entities, the dynamic update is not possible without having the <> annotation as well. -==== - -[[annotations-hibernate-embeddableinstantiator]] -==== `@EmbeddableInstantiator` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/EmbeddableInstantiator.html[`@EmbeddableInstantiator`] annotation is used to specify a custom instantiator for a specific embedded. - -See the <> section for more info. - -[[annotations-hibernate-embeddableinstantiatorregistration]] -==== `@EmbeddableInstantiatorRegistration` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/EmbeddableInstantiatorRegistration.html[`@EmbeddableInstantiatorRegistration`] annotation is used to register a custom instantiator implementation to be used for all references to a particular Embeddable. - -See the <> section for more info. - -[[annotations-hibernate-embeddableinstantiatorregistrations]] -==== `@EmbeddableInstantiatorRegistrations` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/EmbeddableInstantiatorRegistrations.html[`@EmbeddableInstantiatorRegistrations`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-fetch]] -==== `@Fetch` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Fetch.html[`@Fetch`] annotation is used to specify the Hibernate specific https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FetchMode.html[`FetchMode`] (e.g. `JOIN`, `SELECT`, `SUBSELECT`) used for the currently annotated association. - -See the <> section for more info. - -[[annotations-hibernate-fetchprofile]] -==== `@FetchProfile` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FetchProfile.html[`@FetchProfile`] annotation is used to specify a custom fetching profile, similar to a Jakarta Persistence Entity Graph. - -See the <> section for more info. - -[[annotations-hibernate-fetchprofile-fetchoverride]] -==== `@FetchProfile.FetchOverride` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FetchProfile.FetchOverride.html[`@FetchProfile.FetchOverride`] annotation is used in conjunction with the <> annotation, -and it's used for overriding the fetching strategy of a particular entity association. - -See the <> section for more info. - -[[annotations-hibernate-fetchprofiles]] -==== `@FetchProfiles` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FetchProfiles.html[`@FetchProfiles`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-filter]] -==== `@Filter` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Filter.html[`@Filter`] annotation is used to add filters to an entity or the target entity of a collection. - -See the <> section for more info. - -[[annotations-hibernate-filterdef]] -==== `@FilterDef` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FilterDef.html[`@FilterDef`] annotation is used to specify a `@Filter` definition (name, default condition and parameter types, if any). - -See the <> section for more info. - -[[annotations-hibernate-filterdefs]] -==== `@FilterDefs` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FilterDefs.html[`@FilterDefs`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-filterjointable]] -==== `@FilterJoinTable` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FilterJoinTable.html[`@FilterJoinTable`] annotation is used to add `@Filter` capabilities to a join table collection. - -See the <> section for more info. - -[[annotations-hibernate-filterjointables]] -==== `@FilterJoinTables` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/FilterJoinTables.html[`@FilterJoinTables`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-filters]] -==== `@Filters` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Filters.html[`@Filters`] annotation is used to group multiple <> annotations. - -==== [line-through]#`@ForeignKey`# - - -[[annotations-hibernate-formula]] -==== `@Formula` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Formula.html[`@Formula`] annotation is used to specify an SQL fragment that is executed in order to populate a given entity attribute. - -See the <> section for more info. - -[[annotations-hibernate-generated]] -==== `@Generated` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Generated.html[`@Generated`] annotation is used to specify that the currently annotated entity attribute is generated by the database. - -See the <> section for more info. - -[[annotations-hibernate-generatedcolumn]] -==== `@GeneratedColumn` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/GeneratedColumn.html[`@GeneratedColumn`] annotation is used to specify that an entity attribute is generated by the database using `GENERATED ALWAYS AS` DDL. - -[[annotations-hibernate-generatortype]] -==== `@GeneratorType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/GeneratorType.html[`@GeneratorType`] annotation is used to provide a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tuple/ValueGenerator.html[`ValueGenerator`] -and a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/GenerationTime.html[`GenerationTime`] for the currently annotated generated attribute. - -See the <> section for more info. - -[[annotations-hibernate-genericgenerator]] -==== `@GenericGenerator` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/GenericGenerator.html[`@GenericGenerator`] annotation can be used to configure any Hibernate identifier generator. - -See the <> section for more info. - -[[annotations-hibernate-genericgenerators]] -==== `@GenericGenerators` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/GenericGenerators.html[`@GenericGenerators`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-immutable]] -==== `@Immutable` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Immutable.html[`@Immutable`] annotation is used to specify that the annotated entity, attribute, or collection is immutable. - -See the <> section for more info. - -[[annotations-hibernate-index]] -==== [line-through]#`@Index`# - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Index.html[[line-through]#`@Index`#] annotation is deprecated. Use the Jakarta Persistence <> annotation instead. - -[[annotations-hibernate-indexcolumn]] -==== [line-through]#`@IndexColumn`# - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/IndexColumn.html[[line-through]#`@IndexColumn`#] annotation is deprecated. Use the Jakarta Persistence <> annotation instead. - -[[annotations-hibernate-joincolumnorformula]] -==== `@JoinColumnOrFormula` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/JoinColumnOrFormula.html[`@JoinColumnOrFormula`] annotation is used to specify that the entity association is resolved either through a FOREIGN KEY join (e.g. <>) or using the result of a given SQL formula (e.g. <>). - -See the <> section for more info. - -[[annotations-hibernate-joincolumnsorformulas]] -==== `@JoinColumnsOrFormulas` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/JoinColumnsOrFormulas.html[`@JoinColumnsOrFormulas`] annotation is used to group multiple <> annotations. -[[annotations-hibernate-joinformula]] -==== `@JoinFormula` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/JoinFormula.html[`@JoinFormula`] annotation is used as a replacement for <> when the association does not have a dedicated FOREIGN KEY column. - -See the <> section for more info. - -[[annotations-hibernate-lazycollection]] -==== `@LazyCollection` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Index.html[[line-through]#`@LazyCollection`#] annotation is deprecated. - -[[annotations-hibernate-lazygroup]] -==== `@LazyGroup` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/LazyGroup.html[`@LazyGroup`] annotation is used to specify that an entity attribute should be fetched along with all the other attributes belonging to the same group. - -To load entity attributes lazily, bytecode enhancement is needed. -By default, all non-collection attributes are loaded in one group named "DEFAULT". - -This annotation allows defining different groups of attributes to be initialized together when access one attribute in the group. - -See the <> section for more info. - -[[annotations-hibernate-lazytoone]] -==== `@LazyToOne` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Index.html[[line-through]#`@LazyToOne`#] annotation is deprecated. - -[[annotations-hibernate-listindexbase]] -==== `@ListIndexBase` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ListIndexBase.html[`@ListIndexBase`] annotation is used to specify the start value for a list index, as stored in the database. - -By default, `List` indexes are stored starting at zero. Generally used in conjunction with <>. - -See the <> section for more info. - -[[annotations-hibernate-loader]] -==== `@Loader` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Loader.html[`@Loader`] annotation is used to override the default `SELECT` query used for loading an entity. - -See the <> section for more info. - -[[annotations-hibernate-manytoany]] -==== `@ManyToAny` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ManyToAny.html[`@ManyToAny`] annotation is used to specify a many-to-one association when the target type is dynamically resolved. - -See the <> section for more info. - -[[annotations-hibernate-mapkeytype]] -==== `@MapKeyType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/MapKeyType.html[`@MapKeyType`] annotation is used to specify the map key type. - -See the <> section for more info. - -[[annotations-hibernate-metavalue]] -==== `@MetaValue` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/MetaValue.html[`@MetaValue`] annotation is used by the <> annotation to specify the association between a given discriminator value and an entity type. - -See the <> section for more info. - -[[annotations-hibernate-namednativequeries]] -==== `@NamedNativeQueries` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NamedNativeQueries.html[`@NamedNativeQueries`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-namednativequery]] -==== `@NamedNativeQuery` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NamedNativeQuery.html[`@NamedNativeQuery`] annotation extends the Jakarta Persistence <> with Hibernate specific features, like: - -- flush mode for this particular query -- if the query should be cached, and which cache region should be used -- the selected entity `CacheModeType` strategy -- the JDBC `Statement` fetch size -- the JDBC `Statement` execution timeout -- if the query is a `CallableStatement`, targeting a stored procedure or a database function -- what SQL-level comment should be sent to the database -- if the query is read-only, hence it does not store the resulted entities into the currently running Persistence Context - -See the <> section for more info. - -[[annotations-hibernate-namedqueries]] -==== `@NamedQueries` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NamedQueries.html[`@NamedQueries`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-namedquery]] -==== `@NamedQuery` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NamedQuery.html[`@NamedQuery`] annotation extends the Jakarta Persistence <> with Hibernate specific features, like: - -- flush mode for this particular query -- if the query should be cached, and which cache region should be used -- the selected entity `CacheModeType` strategy -- the JDBC `Statement` fetch size -- the JDBC `Statement` execution timeout -- if the query is a `CallableStatement`, targeting a stored procedure or a database function -- what SQL-level comment should be sent to the database -- if the query is read-only, hence it does not store the resulted entities into the currently running Persistence Context - -See the <> section for more info. - -[[annotations-hibernate-nationalized]] -==== `@Nationalized` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Nationalized.html[`@Nationalized`] annotation is used to specify that the currently annotated attribute is a character type (e.g. `String`, `Character`, `Clob`) that is stored in a nationalized column type (`NVARCHAR`, `NCHAR`, `NCLOB`). - -See the <> section for more info. - -[[annotations-hibernate-naturalid]] -==== `@NaturalId` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NaturalId.html[`@NaturalId`] annotation is used to specify that the currently annotated attribute is part of the natural id of the entity. - -See the <> section for more info. - -[[annotations-hibernate-naturalidcache]] -==== `@NaturalIdCache` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NaturalIdCache.html[`@NaturalIdCache`] annotation is used to specify that the natural id values associated with the annotated entity should be stored in the second-level cache. - -See the <> section for more info. - -[[annotations-hibernate-notfound]] -==== `@NotFound` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NotFound.html[`@NotFound`] annotation is used to specify the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/NotFoundAction.html[`NotFoundAction`] strategy for when an element is not found in a given association. - -The `NotFoundAction` defines two possibilities: - -`EXCEPTION`:: An exception is thrown when an element is not found (default and recommended). -`IGNORE`:: Ignore the element when not found in the database. - -See the <> section for more info. - -[[annotations-hibernate-ondelete]] -==== `@OnDelete` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/OnDelete.html[`@OnDelete`] annotation is used to specify the delete strategy employed by the currently annotated collection, array or joined subclasses. -This annotation is used by the automated schema generation tool to generated the appropriate FOREIGN KEY DDL cascade directive. - -The two possible strategies are defined by the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/OnDeleteAction.html[`OnDeleteAction`] enumeration: - -CASCADE:: Use the database FOREIGN KEY cascade capabilities. -NO_ACTION:: Take no action. - -See the <> chapter for more info. - -[[annotations-hibernate-optimisticlock]] -==== `@OptimisticLock` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/OptimisticLock.html[`@OptimisticLock`] annotation is used to specify if the currently annotated attribute will trigger an entity version increment upon being modified. - -See the <> section for more info. - -[[annotations-hibernate-optimisticlocking]] -==== `@OptimisticLocking` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/OptimisticLocking.html[`@OptimisticLocking`] annotation is used to specify the currently annotated entity's optimistic locking strategy. - -The four possible strategies are defined by the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/OptimisticLockType.html[`OptimisticLockType`] enumeration: - -NONE:: The implicit optimistic locking mechanism is disabled. -VERSION:: The implicit optimistic locking mechanism is using a dedicated version column. -ALL:: The implicit optimistic locking mechanism is using *all* attributes as part of an expanded WHERE clause restriction for the `UPDATE` and `DELETE` SQL statements. -DIRTY:: The implicit optimistic locking mechanism is using the *dirty* attributes (the attributes that were modified) as part of an expanded WHERE clause restriction for the `UPDATE` and `DELETE` SQL statements. - -See the <> section for more info. - -[[annotations-hibernate-orderby]] -==== `@OrderBy` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/OrderBy.html[`@OrderBy`] annotation is used to specify a *SQL* ordering directive for sorting the currently annotated collection. - -It differs from the Jakarta Persistence <> annotation because the Jakarta Persistence annotation expects a JPQL order-by fragment, not an SQL directive. - -See the <> section for more info. - -[[annotations-hibernate-paramdef]] -==== `@ParamDef` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ParamDef.html[`@ParamDef`] annotation is used in conjunction with <> so that the Hibernate Filter can be customized with runtime-provided parameter values. - -See the <> section for more info. - -[[annotations-hibernate-parameter]] -==== `@Parameter` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Parameter.html[`@Parameter`] annotation is a generic parameter (basically a key/value combination) used to parametrize other annotations, -like <>, <>, and <>, <>. - -[[annotations-hibernate-parent]] -==== `@Parent` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Parent.html[`@Parent`] annotation is used to specify that the currently annotated embeddable attribute references back the owning entity. - -See the <> section for more info. - -[[annotations-hibernate-partition-key]] -==== `@PartitionKey` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/PartitionKey.html[`@PartitionKey`] annotation is used to identify a field of an entity that holds the partition key of a table. - -See the <> section for more info. - -[[annotations-hibernate-persister]] -==== `@Persister` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Persister.html[`@Persister`] annotation is used to specify a custom entity or collection persister. - -For entities, the custom persister must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/entity/EntityPersister.html[`EntityPersister`] interface. - -For collections, the custom persister must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/collection/CollectionPersister.html[`CollectionPersister`] interface. - -See the <> section for more info. - -[[annotations-hibernate-polymorphism]] -==== `@Polymorphism` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Polymorphism.html[`@Polymorphism`] annotation is used to define the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/PolymorphismType.html[`PolymorphismType`] Hibernate will apply to entity hierarchies. - -There are two possible `PolymorphismType` options: - -EXPLICIT:: The currently annotated entity is retrieved only if explicitly asked. -IMPLICIT:: The currently annotated entity is retrieved if any of its super entities are retrieved. This is the default option. - -See the <> section for more info. - -[[annotations-hibernate-proxy]] -==== `@Proxy` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Proxy.html[`@Proxy`] annotation is used to specify a custom proxy implementation for the currently annotated entity. - -See the <> section for more info. - -[[annotations-hibernate-rowid]] -==== `@RowId` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/RowId.html[`@RowId`] annotation is used to specify the database column used as a `ROWID` _pseudocolumn_. -For instance, Oracle defines the https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns008.htm[`ROWID` pseudocolumn] which provides the address of every table row. - -According to Oracle documentation, `ROWID` is the fastest way to access a single row from a table. - -See the <> section for more info. - -[[annotations-hibernate-selectbeforeupdate]] -==== `@SelectBeforeUpdate` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SelectBeforeUpdate.html[`@SelectBeforeUpdate`] annotation is used to specify that the currently annotated entity state be selected from the database when determining whether to perform an update when the detached entity is reattached. - -See the <> section for more info on how `@SelectBeforeUpdate` works. - -[[annotations-hibernate-sortcomparator]] -==== `@SortComparator` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SortComparator.html[`@SortComparator`] annotation is used to specify a `Comparator` for sorting the `Set`/`Map` in-memory. - -See the <> section for more info. - -[[annotations-hibernate-sortnatural]] -==== `@SortNatural` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SortNatural.html[`@SortNatural`] annotation is used to specify that the `Set`/`Map` should be sorted using natural sorting. - -See the <> section for more info. - -[[annotations-hibernate-source]] -==== `@Source` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Source.html[`@Source`] annotation is used in conjunction with a `@Version` timestamp entity attribute indicating -the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SourceType.html[`SourceType`] of the timestamp value. - -The `SourceType` offers two options: - -DB:: Get the timestamp from the database. -VM:: Get the timestamp from the current JVM. - -See the <> section for more info. - -[[annotations-hibernate-sqldelete]] -==== `@SQLDelete` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SQLDelete.html[`@SQLDelete`] annotation is used to specify a custom SQL `DELETE` statement for the currently annotated entity or collection. - -See the <> section for more info. - -[[annotations-hibernate-sqldeleteall]] -==== `@SQLDeleteAll` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SQLDeleteAll.html[`@SQLDeleteAll`] annotation is used to specify a custom SQL `DELETE` statement when removing all elements of the currently annotated collection. - -See the <> section for more info. - -[[annotations-hibernate-sqlfragmentalias]] -==== `@SqlFragmentAlias` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SqlFragmentAlias.html[`@SqlFragmentAlias`] annotation is used to specify an alias for a Hibernate <>. - -The alias (e.g. `myAlias`) can then be used in the `@Filter` `condition` clause using the `{alias}` (e.g. `{myAlias}`) placeholder. - -See the <> section for more info. - -[[annotations-hibernate-sqlinsert]] -==== `@SQLInsert` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SQLInsert.html[`@SQLInsert`] annotation is used to specify a custom SQL `INSERT` statement for the currently annotated entity or collection. - -See the <> section for more info. - -[[annotations-hibernate-sqlupdate]] -==== `@SQLUpdate` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SQLUpdate.html[`@SQLUpdate`] annotation is used to specify a custom SQL `UPDATE` statement for the currently annotated entity or collection. - -See the <> section for more info. - -[[annotations-hibernate-subselect]] -==== `@Subselect` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Subselect.html[`@Subselect`] annotation is used to specify an immutable and read-only entity using a custom SQL `SELECT` statement. - -See the <> section for more info. - -[[annotations-hibernate-synchronize]] -==== `@Synchronize` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Synchronize.html[`@Synchronize`] annotation is usually used in conjunction with the <> annotation to specify the list of database tables used by the `@Subselect` SQL query. - -With this information in place, Hibernate will properly trigger an entity flush whenever a query targeting the `@Subselect` entity is to be executed while the Persistence Context has scheduled some insert/update/delete actions against the database tables used by the `@Subselect` SQL query. - -Therefore, the `@Synchronize` annotation prevents the derived entity from returning stale data when executing entity queries against the `@Subselect` entity. - -See the <> section for more info. - -[[annotations-hibernate-table]] -==== `@Table` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Table.html[`@Table`] annotation is used to specify additional information to a Jakarta Persistence <> annotation, like custom `INSERT`, `UPDATE` or `DELETE` statements or a specific https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/FetchMode.html[`FetchMode`]. - -See the <> section for more info about Hibernate-specific `@Table` mapping. - -[[annotations-hibernate-tables]] -==== `@Tables` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Tables.html[`@Tables`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-target]] -==== `@Target` -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Target.html[`@Target`] annotation is used to specify an explicit target implementation when the currently annotated association is using an interface type. - -See the <> section for more info. - -[[annotations-hibernate-tuplizer]] -==== `@Tuplizer` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Tuplizer.html[`@Tuplizer`] annotation is used to specify a custom tuplizer for the currently annotated entity or embeddable. - -For entities, the tupelizer must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tuple/entity/EntityTuplizer.html[`EntityTuplizer`] interface. - -For embeddables, the tupelizer must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tuple/component/ComponentTuplizer.html[`ComponentTuplizer`] interface. - -See the <> section for more info. - -[[annotations-hibernate-tuplizers]] -==== `@Tuplizers` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Tuplizers.html[`@Tuplizers`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-type]] -==== `@Type` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Type.html[`@Type`] annotation is used to specify the Hibernate https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/type/Type.html[`@Type`] used by the currently annotated basic attribute. - -See the <> section for more info. - -[[annotations-hibernate-typedef]] -==== `@TypeDef` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/TypeDef.html[`@TypeDef`] annotation is used to specify a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/type/Type.html[`@Type`] definition which can later be reused for multiple basic attribute mappings. - -See the <> section for more info. - -[[annotations-hibernate-typedefs]] -==== `@TypeDefs` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/TypeDefs.html[`@TypeDefs`] annotation is used to group multiple <> annotations. - -[[annotations-hibernate-updatetimestamp]] -==== `@UpdateTimestamp` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/UpdateTimestamp.html[`@UpdateTimestamp`] annotation is used to specify that the currently annotated timestamp attribute should be updated with the current JVM timestamp whenever the owning entity gets modified. - -The supported property types are: - -- `java.util.Date` -- `java.util.Calendar` -- `java.sql.Date` -- `java.sql.Time` -- `java.sql.Timestamp` -- `java.time.Instant` -- `java.time.LocalDate` -- `java.time.LocalDateTime` -- `java.time.LocalTime` -- `java.time.MonthDay` -- `java.time.OffsetDateTime` -- `java.time.OffsetTime` -- `java.time.Year` -- `java.time.YearMonth` -- `java.time.ZonedDateTime` - -See the <> section for more info. - -[[annotations-hibernate-valuegenerationtype]] -==== `@ValueGenerationType` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ValueGenerationType.html[`@ValueGenerationType`] annotation is used to specify that the current annotation type should be used as a generator annotation type. - -See the <> section for more info. - -[[annotations-hibernate-where]] -==== `@SQLRestriction` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SQLRestriction.html[`@SQLRestriction`] annotation is used to specify a custom SQL `WHERE` clause used to filter out entities or collections. - -See the <> section for more info. - -[[annotations-hibernate-wherejointable]] -==== `@SQLJoinTableRestriction` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/SQLJoinTableRestriction.html[`@SQLJoinTableRestriction`] annotation is used to specify a custom SQL `WHERE` clause used when fetching a join collection table. - -See the <> section for more info. - - -[[annotations-hibernate-tenantid]] -==== `@TenantId` - -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/TenantId.html[`@TenantId`] annotation identifies a field of an entity that holds a tenant id in discriminator-based multitenancy. diff --git a/documentation/src/main/asciidoc/userguide/appendices/BestPractices.adoc b/documentation/src/main/asciidoc/userguide/appendices/BestPractices.adoc index 6552ebad79..d64170c723 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/BestPractices.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/BestPractices.adoc @@ -258,8 +258,3 @@ For this reason, `NONSTRICT_READ_WRITE` is not very suitable if entities are cha When using clustering, the second-level cache entries are spread across multiple nodes. When using https://infinispan.org/blog/2015/10/01/hibernate-second-level-cache/[Infinispan distributed cache], only `READ_WRITE` and `NONSTRICT_READ_WRITE` are available for read-write caches. Bear in mind that `NONSTRICT_READ_WRITE` offers a weaker consistency guarantee since stale updates are possible. - -[NOTE] -==== -For more about Hibernate Performance Tuning, check out the https://www.youtube.com/watch?v=BTdTEe9QL5k&t=1s[High-Performance Hibernate] presentation from Devoxx France. -==== \ No newline at end of file diff --git a/documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc b/documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc deleted file mode 100644 index c21aec552d..0000000000 --- a/documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc +++ /dev/null @@ -1,1185 +0,0 @@ -[[configurations]] -== Configurations - -[[configurations-strategy]] -=== Strategy configurations - -Many configuration settings define pluggable strategies that Hibernate uses for various purposes. -The configurations of many of these strategy type settings accept definition in various forms. -The documentation of such configuration settings refers here. -The types of forms available in such cases include: - -short name (if defined):: - Certain built-in strategy implementations have a corresponding short name -strategy instance:: - An instance of the strategy implementation to use can be specified -strategy Class reference:: - A `java.lang.Class` reference of the strategy implementation to use -strategy Class name:: - The class name (`java.lang.String`) of the strategy implementation to use - -[[configurations-general]] -=== General configuration - -`*hibernate.dialect*` (e.g. `org.hibernate.dialect.PostgreSQLDialect`):: -The class name of a Hibernate https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/dialect/Dialect.html[`Dialect`] from which Hibernate can generate SQL optimized for a particular relational database. -+ -In most cases, Hibernate can choose the correct https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/dialect/Dialect.html[`Dialect`] implementation based on the JDBC metadata returned by the JDBC driver. -+ -`*hibernate.current_session_context_class*` (e.g. `jta`, `thread`, `managed`, or a custom class implementing `org.hibernate.context.spi.CurrentSessionContext`):: -+ -Supplies a custom strategy for the scoping of the _current_ `Session`. -+ -The definition of what exactly _current_ means is controlled by the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/context/spi/CurrentSessionContext.html[`CurrentSessionContext`] implementation in use. -+ -Note that for backward compatibility, if a `CurrentSessionContext` is not configured but JTA is configured this will default to the `JTASessionContext`. - -[[configurations-jpa-compliance]] -=== Jakarta Persistence compliance - -`*hibernate.jpa.compliance.transaction*` (e.g. `true` or `false` (default value)):: -This setting controls if Hibernate `Transaction` should behave as defined by the spec for Jakarta Persistence's `jakarta.persistence.EntityTransaction` -since it extends the Jakarta Persistence one. - -`*hibernate.jpa.compliance.query*` (e.g. `true` or `false` (default value)):: -Controls whether Hibernate's handling of `jakarta.persistence.Query` (JPQL, Criteria and native query) should strictly follow the Jakarta Persistence spec. -+ -This includes both in terms of parsing or translating a query as well as calls to the `jakarta.persistence.Query` methods throwing spec -defined exceptions whereas Hibernate might not. - -`*hibernate.jpa.compliance.list*` (e.g. `true` or `false` (default value)):: -Controls whether Hibernate should recognize what it considers a "bag" (`org.hibernate.collection.internal.PersistentBag`) -as a List (`org.hibernate.collection.internal.PersistentList`) or as a bag. -+ -If enabled, we will recognize it as a List where `jakarta.persistence.OrderColumn` -is just missing (and its defaults will apply). - -`*hibernate.jpa.compliance.closed*` (e.g. `true` or `false` (default value)):: -Jakarta Persistence defines specific exceptions upon calling specific methods on `jakarta.persistence.EntityManager` and `jakarta.persistence.EntityManagerFactory` -objects which have been closed previously. -+ -This setting controls whether the Jakarta Persistence spec-defined behavior or the Hibernate behavior will be used. -+ -If enabled, Hibernate will operate in the Jakarta Persistence specified way, throwing exceptions when the spec says it should. - -`*hibernate.jpa.compliance.proxy*` (e.g. `true` or `false` (default value)):: -The Jakarta Persistence spec says that a `jakarta.persistence.EntityNotFoundException` should be thrown when accessing an entity proxy -which does not have an associated table row in the database. -+ -Traditionally, Hibernate does not initialize an entity proxy when accessing its identifier since we already know the identifier value, -hence we can save a database roundtrip. -+ -If enabled Hibernate will initialize the entity proxy even when accessing its identifier. - -`*hibernate.jpa.compliance.global_id_generators*` (e.g. `true` or `false` (default value) ):: -The Jakarta Persistence spec says that the scope of TableGenerator and SequenceGenerator names is global to the persistence unit (across all generator types). -+ -Traditionally, Hibernate has considered the names locally scoped. -+ -If enabled, the names used by `@TableGenerator` and `@SequenceGenerator` will be considered global so configuring two different generators -with the same name will cause a `java.lang.IllegalArgumentException` to be thrown at boot time. - -[[configurations-database-connection]] -=== Database connection properties - -`*hibernate.connection.driver_class*` or `*jakarta.persistence.jdbc.driver*` (e.g. `org.postgresql.Driver`):: -Names the JDBC `Driver` class name. - -`*hibernate.connection.url*` or `*jakarta.persistence.jdbc.url*` (e.g. `jdbc:postgresql:hibernate_orm_test`):: -Names the JDBC connection URL. - -`*hibernate.connection.username*` or `*jakarta.persistence.jdbc.user*`:: -Names the JDBC connection user name. - -`*hibernate.connection.password*` or `*jakarta.persistence.jdbc.password*`:: -Names the JDBC connection password. - -`*hibernate.connection.isolation*` (e.g. `REPEATABLE_READ` or `Connection.TRANSACTION_REPEATABLE_READ`):: -Names the JDBC connection transaction isolation level. - -`*hibernate.connection.autocommit*` (e.g. `true` or `false` (default value)):: -Names the initial autocommit mode for JDBC Connections returned from a connection pool created in certain ConnectionProvider impl. -+ -See discussion of `hibernate.connection.provider_disables_autocommit` as well. - -`*hibernate.connection.provider_disables_autocommit*` (e.g. `true` or `false` (default value)):: -Indicates a promise by the user that Connections that Hibernate obtains from the configured ConnectionProvider -have auto-commit disabled when they are obtained from that provider, whether that provider is backed by -a DataSource or some other Connection pooling mechanism. Generally, this occurs when: -* Hibernate is configured to get Connections from an underlying DataSource, and that DataSource is already configured to disable auto-commit on its managed Connections. -* Hibernate is configured to get Connections from a non-DataSource connection pool and that connection pool is already configured to disable auto-commit. -For the Hibernate provided implementation this will depend on the value of `hibernate.connection.autocommit` setting. -+ -Hibernate uses this assurance as an opportunity to opt out of certain operations that may have a performance -impact (although this impact is generally negligible). Specifically, when a transaction is started via the -Hibernate or Jakarta Persistence transaction APIs Hibernate will generally immediately acquire a Connection from the -provider and: -* check whether the Connection is initially in auto-commit mode via a call to `Connection#getAutocommit` to know how to clean up the Connection when released. -* start a JDBC transaction by calling `Connection#setAutocommit(false)`. -+ -We can skip both of those steps if we know that the ConnectionProvider will always return Connections with auto-commit disabled. -That is the purpose of this setting. By setting it to `true`, the `Connection` acquisition can be delayed until the first -SQL statement is needed to be executed. The connection acquisition delay allows you to reduce the database connection lease -time, therefore allowing you to increase the transaction throughput. -+ -==== -It is *inappropriate* to set this value to `true` when the Connections Hibernate gets -from the provider do not, in fact, have auto-commit disabled. - -Doing so will lead to Hibernate executing SQL operations outside of any JDBC/SQL transaction. -==== - -`*hibernate.connection.handling_mode*`:: -Specifies how Hibernate should manage JDBC connections in terms of acquiring and releasing. -+ -The connection handling mode strategies are defined by the -https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/resource/jdbc/spi/PhysicalConnectionHandlingMode.html[`PhysicalConnectionHandlingMode`] enumeration. -+ -The configuration can be either a `PhysicalConnectionHandlingMode` reference or its case-insensitive `String` representation. -+ -For more details about the `PhysicalConnectionHandlingMode` and Hibernate connection handling, check out the -<> section. - -`*hibernate.connection.datasource*`:: -Either a `javax.sql.DataSource` instance or a JNDI name under which to locate the `DataSource`. -+ -For JNDI names, ses also `hibernate.jndi.class`, `hibernate.jndi.url`, `hibernate.jndi`. - -`*hibernate.connection*`:: - Names a prefix used to define arbitrary JDBC connection properties. These properties are passed along to the JDBC provider when creating a connection. -`*hibernate.connection.provider_class*` (e.g. `org.hibernate.hikaricp.internal. HikariCPConnectionProvider`):: -Names the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/connections/spi/ConnectionProvider.html[`ConnectionProvider`] to use for obtaining JDBC connections. -+ -Can reference: -+ -** an instance of `ConnectionProvider` -** a `Class` object reference -** a fully qualified name of a class implementing `ConnectionProvider` -+ - -The term `class` appears in the setting name due to legacy reasons. However, it can accept instances. - -`*hibernate.jndi.class*`:: -Names the JNDI `javax.naming.InitialContext` class. - -`*hibernate.jndi.url*` (e.g. `java:global/jdbc/default`):: -Names the JNDI provider/connection url. - -`*hibernate.jndi*`:: -Names a prefix used to define arbitrary JNDI `javax.naming.InitialContext` properties. -+ -These properties are passed along to `javax.naming.InitialContext#InitialContext(java.util.Hashtable)` method. - -==== Hibernate internal connection pool options - -`*hibernate.connection.initial_pool_size*` (e.g. 1 (default value)):: -Minimum number of connections for the built-in Hibernate connection pool. - -`*hibernate.connection.pool_size*` (e.g. 20 (default value)):: -Maximum number of connections for the built-in Hibernate connection pool. - -`*hibernate.connection.pool_validation_interval*` (e.g. 30 (default value)):: -The number of seconds between two consecutive pool validations. During validation, the pool size can increase or decrease based on the connection acquisition request count. - -[[configurations-c3p0]] -=== c3p0 properties - -`*hibernate.c3p0.min_size*` (e.g. 1):: - Minimum size of C3P0 connection pool. Refers to https://www.mchange.com/projects/c3p0/#minPoolSize[c3p0 `minPoolSize` setting]. - -`*hibernate.c3p0.max_size*` (e.g. 5):: - Maximum size of C3P0 connection pool. Refers to https://www.mchange.com/projects/c3p0/#maxPoolSize[c3p0 `maxPoolSize` setting]. - -`*hibernate.c3p0.timeout*` (e.g. 30):: - Maximum idle time for C3P0 connection pool. Refers to https://www.mchange.com/projects/c3p0/#maxIdleTime[c3p0 `maxIdleTime` setting]. - -`*hibernate.c3p0.max_statements*` (e.g. 5):: - Maximum size of C3P0 statement cache. Refers to https://www.mchange.com/projects/c3p0/#maxStatements[c3p0 `maxStatements` setting]. - -`*hibernate.c3p0.acquire_increment*` (e.g. 2):: - The number of connections acquired at a time when there's no connection available in the pool. Refers to https://www.mchange.com/projects/c3p0/#acquireIncrement[c3p0 `acquireIncrement` setting]. - -`*hibernate.c3p0.idle_test_period*` (e.g. 5):: - Idle time before a C3P0 pooled connection is validated. Refers to https://www.mchange.com/projects/c3p0/#idleConnectionTestPeriod[c3p0 `idleConnectionTestPeriod` setting]. - -`*hibernate.c3p0*`:: - A setting prefix used to indicate additional c3p0 properties that need to be passed to the underlying c3p0 connection pool. - -[[configurations-mapping]] -=== Mapping Properties - -==== Table qualifying options - -`*hibernate.default_catalog*` (e.g. A catalog name):: -Qualifies unqualified table names with the given catalog in generated SQL. - -`*hibernate.default_schema*` (e.g. A schema name):: -Qualify unqualified table names with the given schema or tablespace in generated SQL. - -`*hibernate.schema_name_resolver*` (e.g. The fully qualified name of an https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/env/spi/SchemaNameResolver.html[`org.hibernate.engine.jdbc.env.spi.SchemaNameResolver`] implementation class):: -By default, Hibernate uses the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/dialect/Dialect.html#getSchemaNameResolver--[`org.hibernate.dialect.Dialect#getSchemaNameResolver`]. -You can customize how the schema name is resolved by providing a custom implementation of the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/env/spi/SchemaNameResolver.html[`SchemaNameResolver`] interface. - -==== Identifier options - -`*hibernate.use_identifier_rollback*` (e.g. `true` or `false` (default value)):: -If true, generated identifier properties are reset to default values when objects are deleted. - -`*hibernate.id.optimizer.pooled.preferred*` (e.g. `none`, `hilo`, `legacy-hilo`, `pooled` (default value), `pooled-lo`, `pooled-lotl` or a fully-qualified name of the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/id/enhanced/Optimizer.html[`Optimizer`] implementation):: -When a generator specified an increment-size and an optimizer was not explicitly specified, which of the _pooled_ optimizers should be preferred? - -`*hibernate.id.generator.stored_last_used*` (e.g. `true` (default value) or `false`):: -If true, the value stored in the table used by the `@TableGenerator` is the last value used, if false the value is the next value to be used. - -`*hibernate.model.generator_name_as_sequence_name*` (e.g. `true` (default value) or `false`):: -If true, the value specified by the `generator` attribute of the `@GeneratedValue` annotation should be used as the sequence/table name when no matching -`@SequenceGenerator` or `TableGenerator` is found. -+ -The default value is `true` meaning that `@GeneratedValue.generator()` will be used as the sequence/table name by default. -Users migrating from earlier versions using the legacy `hibernate_sequence` name should disable this setting. - -`*hibernate.ejb.identifier_generator_strategy_provider*` (e.g. fully-qualified class name or an actual https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/jpa/spi/IdentifierGeneratorStrategyProvider.html[`IdentifierGeneratorStrategyProvider`] instance):: -This setting allows you to provide an instance or the class implementing the `org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider` interface, -so you can provide a set of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/id/IdentifierGenerator.html[`IdentifierGenerator`] strategies allowing to override the Hibernate Core default ones. - -`*hibernate.id.disable_delayed_identity_inserts*` (e.g. `true` or `false` (default value)):: -If true, inserts that use generated-identifiers (identity/sequences) will never be delayed and will always be inserted immediately. -This should be used if you run into any errors with `DelayedPostInsertIdentifier` and should be considered a _temporary_ fix. -Please report your mapping that causes the problem to us so we can examine the default algorithm to see if your use case should be included. -+ -The default value is `false` which means Hibernate will use an algorithm to determine if the insert can be delayed or if the insert should be performed immediately. - -`*hibernate.id.sequence.increment_size_mismatch_strategy*` (e.g. `LOG`, `FIX`, `NONE` or `EXCEPTION` (default value)):: -This setting defines the `org.hibernate.id.SequenceMismatchStrategy` used when -Hibernate detects a mismatch between a sequence configuration in an entity mapping -and its database sequence object counterpart. -+ -The default value is given by the `org.hibernate.id.SequenceMismatchStrategy#EXCEPTION`, -meaning that an Exception is thrown when detecting such a conflict. - -==== Quoting options - -`*hibernate.globally_quoted_identifiers*` (e.g. `true` or `false` (default value)):: -Should all database identifiers be quoted. - -`*hibernate.globally_quoted_identifiers_skip_column_definitions*` (e.g. `true` or `false` (default value)):: -Assuming `hibernate.globally_quoted_identifiers` is `true`, this allows the global quoting to skip column-definitions as defined by `jakarta.persistence.Column`, -`jakarta.persistence.JoinColumn`, etc., and while it avoids column-definitions being quoted due to global quoting, they can still be explicitly quoted in the annotation/xml mappings. - -`*hibernate.auto_quote_keyword*` (e.g. `true` or `false` (default value)):: -Specifies whether to automatically quote any names that are deemed keywords. - -==== Time zone storage -`*hibernate.timezone.default_storage*` (e.g. `COLUMN`, `NATIVE`, `NORMALIZE`, `NORMALIZE_UTC`, `AUTO` or `DEFAULT` (default value)):: -Global setting for configuring the default storage for the time zone information for time zone based types. -+ -`NORMALIZE`::: -Legacy behavior (Hibernate ORM 5). -+ -Does not store the time zone information, and instead: -+ -* when persisting to the database, normalizes JDBC timestamps to the -<> or to the JVM default time zone if not set. -* when reading back from the database, sets the offset or zone -of `OffsetDateTime`/`ZonedDateTime` values to the JVM default time zone. -`NORMALIZE_UTC`::: Does not store the time zone information, and instead normalizes timestamps to UTC. -`COLUMN`::: Stores the time zone information in a separate column; works in conjunction with `@TimeZoneColumn`. -`NATIVE`::: Stores the time zone information by using the `with time zone` type. Error if `Dialect#getTimeZoneSupport()` is not `NATIVE`. -`AUTO`::: Stores the time zone information either with `NATIVE` if `Dialect#getTimeZoneSupport()` is `NATIVE`, otherwise uses the `COLUMN` strategy. -`DEFAULT`::: Stores the time zone information either with `NATIVE` if `Dialect#getTimeZoneSupport()` is `NATIVE`, otherwise uses the `NORMALIZE_UTC` strategy. -+ -The default value is given by the {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE}, -meaning that time zone information is not stored by default, but timestamps are normalized instead. -+ -See the discussion https://github.com/hibernate/hibernate-orm/discussions/4201[on GitHub] for additional background info. - -==== Discriminator options -`*hibernate.discriminator.implicit_for_joined*` (e.g. `true` or `false` (default value)):: -The legacy behavior of Hibernate is to not use discriminators for joined inheritance (Hibernate does not need the discriminator). -However, some Jakarta Persistence providers do need the discriminator for handling joined inheritance so, in the interest of portability, this capability has been added to Hibernate too. -+ -Because want to make sure that legacy applications continue to work as well, that puts us in a bind in terms of how to handle _implicit_ discriminator mappings. -The solution is to assume that the absence of discriminator metadata means to follow the legacy behavior _unless_ this setting is enabled. -+ -With this setting enabled, Hibernate will interpret the absence of discriminator metadata as an indication to use the Jakarta Persistence-defined defaults for these absent annotations. -+ -See Hibernate Jira issue https://hibernate.atlassian.net/browse/HHH-6911[HHH-6911] for additional background info. - -`*hibernate.discriminator.ignore_explicit_for_joined*` (e.g. `true` or `false` (default value)):: -The legacy behavior of Hibernate is to not use discriminators for joined inheritance (Hibernate does not need the discriminator). -However, some Jakarta Persistence providers do need the discriminator for handling joined inheritance so, in the interest of portability, this capability has been added to Hibernate too. -+ -Existing applications rely (implicitly or explicitly) on Hibernate ignoring any `DiscriminatorColumn` declarations on joined inheritance hierarchies. -This setting allows these applications to maintain the legacy behavior of `DiscriminatorColumn` annotations being ignored when paired with joined inheritance. -+ -See Hibernate Jira issue https://hibernate.atlassian.net/browse/HHH-6911[HHH-6911] for additional background info. - -==== Naming strategies - -`*hibernate.implicit_naming_strategy*` (e.g. `default` (default value), `jpa`, `legacy-jpa`, `legacy-hbm`, `component-path`):: -Used to specify the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/naming/ImplicitNamingStrategy.html[`ImplicitNamingStrategy`] class to use. -The following short names are defined for this setting: -`default`::: Uses the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/naming/ImplicitNamingStrategyJpaCompliantImpl.html[`ImplicitNamingStrategyJpaCompliantImpl`] -`jpa`::: Uses the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/naming/ImplicitNamingStrategyJpaCompliantImpl.html[`ImplicitNamingStrategyJpaCompliantImpl`] -`legacy-jpa`::: Uses the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/naming/ImplicitNamingStrategyLegacyJpaImpl.html[`ImplicitNamingStrategyLegacyJpaImpl`] -`legacy-hbm`::: Uses the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/naming/ImplicitNamingStrategyLegacyHbmImpl.html[`ImplicitNamingStrategyLegacyHbmImpl`] -`component-path`::: Uses the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/naming/ImplicitNamingStrategyComponentPathImpl.html[`ImplicitNamingStrategyComponentPathImpl`] -+ -If this property happens to be empty, the fallback is to use the `default` strategy. - -`*hibernate.physical_naming_strategy*` (e.g. `org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl` (default value)):: -Used to specify the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/naming/PhysicalNamingStrategy.html[`PhysicalNamingStrategy`] class to use. - -==== Metadata scanning options - -`*hibernate.archive.scanner*`:: -Pass an implementation of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/archive/scan/spi/Scanner.html[`Scanner`]. -By default, https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/archive/scan/internal/StandardScanner.html[`StandardScanner`] is used. -+ -Accepts: -+ -** an actual `Scanner` instance -** a reference to a Class that implements `Scanner` -** a fully qualified name of a Class that implements `Scanner` - -`*hibernate.archive.interpreter*`:: -Pass https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/archive/spi/ArchiveDescriptorFactory.html[`ArchiveDescriptorFactory`] to use in the scanning process. -+ -Accepts: -+ -** an actual `ArchiveDescriptorFactory` instance -** a reference to a Class that implements `ArchiveDescriptorFactory` -** a fully qualified name of a Class that implements `ArchiveDescriptorFactory` -+ - -See information on https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/archive/scan/spi/Scanner.html[`Scanner`] about expected constructor forms. - -`*hibernate.archive.autodetection*` (e.g. `hbm,class` (default value)):: -Identifies a comma-separated list of values indicating the mapping types we should auto-detect during scanning. -+ -Allowable values include: -+ -`class`::: scan classes (e.g. `.class`) to extract entity mapping metadata -`hbm`::: scan `hbm` mapping files (e.g. `hbm.xml`) to extract entity mapping metadata -+ - -By default HBM, annotations, and Jakarta Persistence XML mappings are scanned. -+ -When using Jakarta Persistence, to disable the automatic scanning of all entity classes, the `exclude-unlisted-classes` `persistence.xml` element must be set to true. -Therefore, when setting `exclude-unlisted-classes` to true, only the classes that are explicitly declared in the `persistence.xml` configuration files are going to be taken into consideration. - -`*hibernate.mapping.precedence*` (e.g. `hbm,class` (default value)):: -Used to specify the order in which metadata sources should be processed. -Value is a delimited-list whose elements are defined by https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/cfg/MetadataSourceType.html[`MetadataSourceType`]. -+ -The default is `hbm,class`, therefore `hbm.xml` files are processed first, followed by annotations (combined with `orm.xml` mappings). -+ -When using Jakarta Persistence, the XML mapping overrides a conflicting annotation mapping that targets the same entity attribute. - -==== JDBC-related options - -`*hibernate.use_nationalized_character_data*` (e.g. `true` or `false` (default value)):: -Enable nationalized character support on all string / clob based attribute ( string, char, clob, text, etc. ). - -`*hibernate.jdbc.lob.non_contextual_creation*` (e.g. `true` or `false` (default value)):: -Should we not use contextual LOB creation (aka based on `java.sql.Connection#createBlob()` et al)? The default value for HANA, H2, and PostgreSQL is `true`. - -[[jdbc-time-zone]]`*hibernate.jdbc.time_zone*` (e.g. A `java.util.TimeZone`, a `java.time.ZoneId` or a `String` representation of a `ZoneId`):: -The timezone to use in the JDBC driver, which is supposed to match the database timezone. -+ -Unless specified, the JDBC Driver uses the default JVM time zone. If a different time zone is configured via this setting, the JDBC https://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html#setTimestamp-int-java.sql.Timestamp-java.util.Calendar-[PreparedStatement#setTimestamp] is going to use a `Calendar` instance according to the specified time zone. - -`*hibernate.dialect.oracle.prefer_long_raw*` (e.g. `true` or `false` (default value)):: -This setting applies to Oracle Dialect only, and it specifies whether `byte[]` or `Byte[]` arrays should be mapped to the deprecated `LONG RAW` (when this configuration property value is `true`) or to a `BLOB` column type (when this configuration property value is `false`). - -`*hibernate.type.preferred_boolean_jdbc_type*` (e.g. `-7` for `java.sql.Types.BIT`):: -Global setting identifying the preferred JDBC type code for storing boolean values. The fallback is to ask the Dialect. -Can also specify the name of the constant in `org.hibernate.type.SqlTypes` instead. - -`*hibernate.type.preferred_uuid_jdbc_type*` (e.g. `1` for `java.sql.Types.CHAR` or `3000` for `org.hibernate.types.SqlTypes.UUID` (default value)):: -Global setting identifying the preferred JDBC type code for storing uuid values. -Can also specify the name of the constant in `org.hibernate.type.SqlTypes` instead. - -`*hibernate.type.preferred_duration_jdbc_type*` (e.g. `2` for `java.sql.Types.NUMERIC` (default value) or `3100` for `org.hibernate.types.SqlTypes.INTERVAL_SECOND`):: -Global setting identifying the preferred JDBC type code for storing duration values. -Can also specify the name of the constant in `org.hibernate.type.SqlTypes` instead. - -`*hibernate.type.preferred_instant_jdbc_type*` (e.g. `93` for `java.sql.Types.TIMESTAMP` or `3003` for `org.hibernate.types.SqlTypes.TIMESTAMP_UTC` (default value)):: -Global setting identifying the preferred JDBC type code for storing instant values. -Can also specify the name of the constant in `org.hibernate.type.SqlTypes` instead. - -==== Bean Validation options -`*jakarta.persistence.validation.factory*` (e.g. `jakarta.validation.ValidationFactory` implementation):: -Specify the `javax.validation.ValidationFactory` implementation to use for Bean Validation. - -`*hibernate.check_nullability*` (e.g. `true` or `false`):: -Enable nullability checking. Raises an exception if a property marked as not-null is null. -+ -Default to `false` if Bean Validation is present in the classpath and Hibernate Annotations is used, `true` otherwise. -`*hibernate.validator.apply_to_ddl*` (e.g. `true` (default value) or `false`):: -+ -Bean Validation constraints will be applied in DDL if the automatic schema generation is enabled. -In other words, the database schema will reflect the Bean Validation constraints. -+ -To disable constraint propagation to DDL, set up `hibernate.validator.apply_to_ddl` to `false` in the configuration file. -Such a need is very uncommon and not recommended. - -[[misc-options]] -==== Misc options - -`*hibernate.create_empty_composites.enabled*` (e.g. `true` or `false` (default value)):: - Enable instantiation of composite/embeddable objects when all of its attribute values are `null`. The default (and historical) behavior is that a `null` reference will be used to represent the composite when all of its attributes are ``null``s. -+ -This is an experimental feature that has known issues. It should not be used in production until it is stabilized. See Hibernate Jira issue https://hibernate.atlassian.net/browse/HHH-11936[HHH-11936] for details. - -`*hibernate.entity_dirtiness_strategy*` (e.g. fully-qualified class name or an actual `CustomEntityDirtinessStrategy` instance):: -Setting to identify an `org.hibernate.CustomEntityDirtinessStrategy` to use. - -`*hibernate.type.json_format_mapper*` (e.g. A fully-qualified class name, an instance, or a `Class` object reference):: -Names a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/type/FormatMapper.html[`FormatMapper`] implementation to be applied to the `SessionFactory` for JSON serialization and deserialization. -+ -Can reference a -`FormatMapper` instance, -`FormatMapper` implementation `Class` reference, -`FormatMapper` implementation class name (fully-qualified class name) or -one of the following shorthand constants `jackson` or `jsonb`. -By default, the first of the possible providers that is available in the runtime is used, according to the listing order. -+ -Note that the default serialization format of collections can differ depending on the serialization library. - -`*hibernate.type.xml_format_mapper*` (e.g. A fully-qualified class name, an instance, or a `Class` object reference):: -Names a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/type/FormatMapper.html[`FormatMapper`] implementation to be applied to the `SessionFactory` for XML serialization and deserialization. -+ -Can reference a -`FormatMapper` instance, -`FormatMapper` implementation `Class` reference, -`FormatMapper` implementation class name (fully-qualified class name) or -one of the following shorthand constants `jackson-xml` or `jaxb`. -By default, the first of the possible providers that is available in the runtime is used, according to the listing order. -+ -Note that the default serialization format of collections can differ depending on the serialization library. - -[[configurations-bytecode-enhancement]] -=== Bytecode Enhancement Properties - -`*hibernate.enhancer.enableDirtyTracking*` (e.g. `true` (default value) or `false`):: -Enable dirty tracking feature in runtime bytecode enhancement. This setting is deprecated for removal without a replacement. - -`*hibernate.enhancer.enableLazyInitialization*` (e.g. `true` (default value) or `false`):: -Enable lazy loading feature in runtime bytecode enhancement. This way, even basic types (e.g. `@Basic(fetch = FetchType.LAZY`)) can be fetched lazily. This setting is deprecated for removal without a replacement. - -`*hibernate.enhancer.enableAssociationManagement*` (e.g. `true` or `false` (default value)):: -Enable association management feature in runtime bytecode enhancement which automatically synchronizes a bidirectional association when only one side is changed. - -`*hibernate.bytecode.provider*` (e.g. `bytebuddy` (default value)):: -The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/bytecode/spi/BytecodeProvider.html[`BytecodeProvider`] built-in implementation flavor. Currently, only `bytebuddy` is a valid value, as older deprecated options have been removed. - -[[configurations-query]] -=== Query settings - -`*hibernate.query.plan_cache_max_size*` (e.g. `2048` (default value)):: -The maximum number of entries including: -https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/query/spi/HQLQueryPlan.html[`HQLQueryPlan`], -https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/query/spi/FilterQueryPlan.html[`FilterQueryPlan`], -https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/query/spi/NativeSQLQueryPlan.html[`NativeSQLQueryPlan`]. -+ -Maintained by https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/query/spi/QueryPlanCache.html[`QueryPlanCache`]. - -`*hibernate.query.plan_parameter_metadata_max_size*` (e.g. `128` (default value)):: -The maximum number of strong references associated with `ParameterMetadata` maintained by https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/query/spi/QueryPlanCache.html[`QueryPlanCache`]. - -`*hibernate.order_by.default_null_ordering*` (e.g. `none`, `first` or `last`):: -Defines precedence of null values in `ORDER BY` clause. Defaults to `none` which varies between RDBMS implementation. - -`*hibernate.discriminator.force_in_select*` (e.g. `true` or `false` (default value)):: -For entities which do not explicitly say, should we force discriminators into SQL selects? - -`*hibernate.query.jpaql_strict_compliance*` (e.g. `true` or `false` (default value)):: -Map from tokens in Hibernate queries to SQL tokens, such as function or literal names. -+ -Should we strictly adhere to Jakarta Persistence Query Language (JPQL) syntax, or more broadly support all of Hibernate's superset (HQL)? -+ -Setting this to `true` may cause valid HQL to throw an exception because it violates the JPQL subset. - -`*hibernate.query.startup_check*` (e.g. `true` (default value) or `false`):: -Should named queries be checked during startup? - -`*hibernate.proc.param_null_passing*` (e.g. `true` or `false` (default value)):: -Global setting for whether `null` parameter bindings should be passed to database procedure/function calls as part of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/procedure/ProcedureCall.html[`ProcedureCall`] handling. -Implicitly Hibernate will not pass the `null`, the intention being to allow any default argument values to be applied. -+ -This defines a global setting, which can then be controlled per parameter via `org.hibernate.procedure.ParameterRegistration#enablePassingNulls(boolean)`. -+ -Values are `true` (pass the NULLs) or `false` (do not pass the NULLs). - -`*hibernate.jdbc.log.warnings*` (e.g. `true` or `false`):: -Enable fetching JDBC statement warning for logging. Default value is given by `org.hibernate.dialect.Dialect#isJdbcLogWarningsEnabledByDefault()`. - -`*hibernate.session_factory.statement_inspector*` (e.g. A fully-qualified class name, an instance, or a `Class` object reference):: -Names a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/resource/jdbc/spi/StatementInspector.html[`StatementInspector`] implementation to be applied to every `Session` created by the current `SessionFactory`. -+ -Can reference a -`StatementInspector` instance, -`StatementInspector` implementation `Class` reference or -`StatementInspector` implementation class name (fully-qualified class name). - -`*hibernate.criteria.value_handling_mode*` (e.g. `BIND` (default value) or `INLINE`):: -By default, Criteria queries uses bind parameters for any value passed through the Jakarta Persistence Criteria API. -+ -The {@link org.hibernate.query.criteria.ValueHandlingMode#BIND} mode (default) will use bind variables for any value. -+ -The {@link org.hibernate.query.criteria.ValueHandlingMode#INLINE} mode will inline values as literals. -+ -The default value is {@link org.hibernate.query.criteria.ValueHandlingMode#BIND}. -Valid options are defined by the `org.hibernate.query.criteria.ValueHandlingMode` enum. - -`*hibernate.criteria.copy_tree*` (e.g. `true` or `false` (default value) ):: -The Jakarta Persistence spec says that mutations done to `CriteriaQuery`, `CriteriaUpdate` and `CriteriaDelete` -after such objects were used to create a `jakarta.persistence.Query` may not affect that query. -This requirement makes it necessary to copy these objects because the APIs allow mutations. -+ -If disabled, it is assumed that users do not mutate the criteria query afterwards -and due to that, no copy will be created, which will improve performance. -+ -When bootstrapping Hibernate through the native bootstrap APIs this setting is disabled -i.e. no copies are created to not hurt performance. -When bootstrapping Hibernate through the JPA SPI this setting is enabled. -When enabled, criteria query objects are copied, as required by the Jakarta Persistence specification. - -`*hibernate.query.fail_on_pagination_over_collection_fetch*` (e.g. `true` or `false` (default value)):: -Raises an exception when in-memory pagination over collection fetch is about to be performed. -+ -Disabled by default. Set to true to enable. - -`*hibernate.query.immutable_entity_update_query_handling_mode*` (e.g. `EXCEPTION` or `WARNING` (default value)):: -Defines how `Immutable` entities are handled when executing a bulk update query. -+ -By default, the (`ImmutableEntityUpdateQueryHandlingMode#WARNING`) mode is used, meaning that -a warning log message is issued when an `@Immutable` entity is to be updated via a bulk update statement. -+ -If the (`ImmutableEntityUpdateQueryHandlingMode#EXCEPTION`) mode is used, then a `HibernateException` is thrown instead. - -`*hibernate.query.in_clause_parameter_padding*` (e.g. `true` or `false` (default value)):: -By default, the IN clause expands to include all bind parameter values. -+ -However, for database systems supporting execution plan caching, -there's a better chance of hitting the cache if the number of possible IN clause parameters lowers. -+ -For this reason, we can expand the bind parameters to power-of-two: 4, 8, 16, 32, 64. -This way, an IN clause with 5, 6, or 7 bind parameters will use the 8 IN clause, -therefore reusing its execution plan. - -==== Multi-table bulk HQL operations - -`*hibernate.query.mutation_strategy*` (e.g. A fully-qualified class name, an instance, or a `Class` object reference):: -Provide a custom https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/query/sqm/mutation/spi/SqmMultiTableMutationStrategy.html[`org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy`] implementation for handling multi-table bulk HQL operations. - -`*hibernate.hql.bulk_id_strategy.global_temporary.create_tables*` (e.g. `true` (default value) or `false`):: -For databases that don't support local tables, but just global ones, this configuration property allows you to control whether to CREATE the global tables used for multi-table bulk HQL operations at `SessionFactory` or the `EntityManagerFactory` startup. - -`*hibernate.hql.bulk_id_strategy.global_temporary.drop_tables*` (e.g. `true` or `false` (default value)):: - For databases that don't support local tables, but just global ones, this configuration property allows you to DROP the global tables used for multi-table bulk HQL operations when the `SessionFactory` or the `EntityManagerFactory` is closed. - -`*hibernate.hql.bulk_id_strategy.local_temporary.drop_tables*` (e.g. `true` or `false` (default value)):: -This configuration property allows you to DROP the local temporary tables used for multi-table bulk HQL operations when the `SessionFactory` or `EntityManagerFactory` is closed. This is useful when testing with a single connection pool against different schemas. - -`*hibernate.hql.bulk_id_strategy.persistent.create_tables*` (e.g. `true` (default value) or `false`):: -This configuration property is used by the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/hql/spi/id/persistent/PersistentTableBulkIdStrategy.html[`PersistentTableBulkIdStrategy`], that mimics temporary tables for databases which do not support temporary tables. -It follows a pattern similar to the ANSI SQL definition of the global temporary table using a "session id" column to segment rows from the various sessions. -+ -This configuration property allows you to control whether to CREATE the tables used for multi-table bulk HQL operations at `SessionFactory` or `EntityManagerFactory` startup. - -`*hibernate.hql.bulk_id_strategy.persistent.drop_tables*` (e.g. `true` or `false` (default value)):: -This configuration property is used by the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/hql/spi/id/persistent/PersistentTableBulkIdStrategy.html[`PersistentTableBulkIdStrategy`], that mimics temporary tables for databases which do not support temporary tables. -It follows a pattern similar to the ANSI SQL definition of the global temporary table using a "session id" column to segment rows from the various sessions. -+ -This configuration property allows you to DROP the tables used for multi-table bulk HQL operations when the `SessionFactory` or the `EntityManagerFactory` is closed. - -`*hibernate.hql.bulk_id_strategy.persistent.schema*` (e.g. Database schema name. By default, the `hibernate.default_schema` is used.):: -This configuration property is used by the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/hql/spi/id/persistent/PersistentTableBulkIdStrategy.html[`PersistentTableBulkIdStrategy`], that mimics temporary tables for databases which do not support temporary tables. -It follows a pattern similar to the ANSI SQL definition of the global temporary table using a "session id" column to segment rows from the various sessions. -+ -This configuration property defines the database schema used for storing the temporary tables used for bulk HQL operations. - -`*hibernate.hql.bulk_id_strategy.persistent.catalog*` (e.g. Database catalog name. By default, the `hibernate.default_catalog` is used.):: -This configuration property is used by the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/hql/spi/id/persistent/PersistentTableBulkIdStrategy.html[`PersistentTableBulkIdStrategy`], that mimics temporary tables for databases which do not support temporary tables. -It follows a pattern similar to the ANSI SQL definition of the global temporary table using a "session id" column to segment rows from the various sessions. -+ -This configuration property defines the database catalog used for storing the temporary tables used for bulk HQL operations. - -[[configurations-batch]] -=== Batching properties - -`*hibernate.jdbc.batch_size*` (e.g. 5):: -Maximum JDBC batch size. A nonzero value enables batch updates. - -`*hibernate.order_inserts*` (e.g. `true` or `false` (default value)):: -Forces Hibernate to order SQL inserts by the primary key value of the items being inserted. This preserves batching when using cascading. - -`*hibernate.order_updates*` (e.g. `true` or `false` (default value)):: -Forces Hibernate to order SQL updates by the primary key value of the items being updated. This preserves batching when using cascading and reduces the likelihood of transaction deadlocks in highly-concurrent systems. - -`*hibernate.jdbc.batch_versioned_data*` (e.g. `true`(default value) or `false`):: -Should versioned entities be included in batching? -+ -Set this property to `true` if your JDBC driver returns correct row counts from executeBatch(). This option is usually safe, but is disabled by default. If enabled, Hibernate uses batched DML for automatically versioned data. - -`*hibernate.batch_fetch_style*` (e.g. `LEGACY`(default value)):: -Names the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/loader/BatchFetchStyle.html[`BatchFetchStyle`] to use. -+ -Can specify either the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/loader/BatchFetchStyle.html[`BatchFetchStyle`] name (case insensitively), or a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/loader/BatchFetchStyle.html[`BatchFetchStyle`] instance. `LEGACY` is the default value. - -`*hibernate.jdbc.batch.builder*` (e.g. the fully qualified name of a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.html[`BatchBuilder`] implementation class type or an actual object instance):: - Names the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.html[`BatchBuilder`] implementation to use. - -[[configurations-database-fetch]] -==== Fetching properties - -`*hibernate.max_fetch_depth*` (e.g. a value between `0` and `3`):: -Sets a maximum depth for the outer join fetch tree for single-ended associations. A single-ended association is a one-to-one or many-to-one association. A value of `0` disables default outer join fetching. - -`*hibernate.default_batch_fetch_size*` (e.g. `4`,`8`, or `16`):: -The default size for Hibernate Batch fetching of associations (lazily fetched associations can be fetched in batches to prevent N+1 query problems). - -`*hibernate.jdbc.fetch_size*` (e.g. `0` or an integer):: -A non-zero value determines the JDBC fetch size, by calling `Statement.setFetchSize()`. - -`*hibernate.jdbc.use_scrollable_resultset*` (e.g. `true` or `false`):: -Enables Hibernate to use JDBC2 scrollable resultsets. This property is only relevant for user-supplied JDBC connections. Otherwise, Hibernate uses connection metadata. - -`*hibernate.jdbc.use_get_generated_keys*` (e.g. `true` or `false`):: -Allows Hibernate to use JDBC3 `PreparedStatement.getGeneratedKeys()` to retrieve natively-generated keys after insert. You need the JDBC3+ driver and JRE1.4+. Disable this property if your driver has problems with the Hibernate identifier generators. By default, it tries to detect the driver capabilities from connection metadata. - -`*hibernate.enable_lazy_load_no_trans*` (e.g. `true` or `false` (default value)):: -Allows a detached proxy or lazy collection to be fetched even when not associated with an open session / persistence context, by creating a temporary persistence context when the proxy or collection is accessed. -+ -Enabling this setting can make `LazyInitializationException` go away, but it's much better to use a fetch plan to ensure that needed associations are fully initialized before the session is closed. -+ -IMPORTANT: This setting is not recommended, since it can easily break transaction isolation or lead to data aliasing. - -[[configurations-logging]] -=== Statement logging and statistics - -==== SQL statement logging - -`*hibernate.show_sql*` (e.g. `true` or `false` (default value)):: -Write all SQL statements to the console. This is an alternative to setting the log category `org.hibernate.SQL` to debug. - -`*hibernate.format_sql*` (e.g. `true` or `false` (default value)):: -Pretty-print the SQL in the log and console. - -`*hibernate.highlight_sql*` (e.g. `true` or `false` (default value)):: -Colorize the SQL in the console using ANSI escape codes. - -`*hibernate.use_sql_comments*` (e.g. `true` or `false` (default value)):: -If true, Hibernate generates comments inside the SQL, for easier debugging. - -==== Statistics settings - -`*hibernate.generate_statistics*` (e.g. `true` or `false`):: -Causes Hibernate to collect statistics for performance tuning. - -`*hibernate.stats.factory*` (e.g. the fully qualified name of a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/stat/spi/StatisticsFactory.html[`StatisticsFactory`] implementation or an actual instance):: -The `StatisticsFactory` allow you to customize how the Hibernate Statistics are being collected. - -`*hibernate.session.events.log*` (e.g. `true` or `false`):: -A setting to control whether the `org.hibernate.engine.internal.StatisticalLoggingSessionEventListener` is enabled on all `Sessions` (unless explicitly disabled for a given `Session`). -+ -The default value of this setting is determined by the value for `hibernate.generate_statistics`, meaning that if statistics are enabled, then logging of Session metrics is enabled by default too. - -[[configurations-cache]] -=== Cache Properties - -`*hibernate.cache.region.factory_class*` (e.g. `jcache`):: -Either a shortcut name (e.g. `jcache`, `ehcache`) or the fully-qualified name of the `RegionFactory` implementation class. - -`*hibernate.cache.default_cache_concurrency_strategy*`:: -Setting used to give the name of the default https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/CacheConcurrencyStrategy.html[`CacheConcurrencyStrategy`] to use -when `@jakarta.persistence.Cacheable`, `@org.hibernate.annotations.Cache` or `@org.hibernate.annotations.Cache` is used to override the global setting. - -`*hibernate.cache.use_minimal_puts*` (e.g. `true` (default value) or `false`):: -Optimizes second-level cache operation to minimize writes, at the cost of more frequent reads. This is most useful for clustered caches and is enabled by default for clustered cache implementations. - -`*hibernate.cache.use_query_cache*` (e.g. `true` or `false` (default value)):: -Enables the query cache. You still need to set individual queries to be cachable. - -`*hibernate.cache.use_second_level_cache*` (e.g. `true` (default value) or `false`):: -Enable/disable the second-level cache, which is enabled by default, although the default `RegionFactor` is `NoCachingRegionFactory` (meaning there is no actual caching implementation). - -`*hibernate.cache.query_cache_factory*` (e.g. fully-qualified class name):: -A custom https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/cache/spi/TimestampsCacheFactory.html[`TimestampsCacheFactory`] interface. The default is the built-in `StandardTimestampsCacheFactory`. - -`*hibernate.cache.region_prefix*` (e.g. A string):: -A prefix for second-level cache region names. - -`*hibernate.cache.use_structured_entries*` (e.g. `true` or `false` (default value)):: -Forces Hibernate to store data in the second-level cache in a more human-readable format. - -`*hibernate.cache.auto_evict_collection_cache*` (e.g. `true` or `false` (default: false)):: -Enables the automatic eviction of a bi-directional association's collection cache when an element in the `ManyToOne` collection is added/updated/removed without properly managing the change on the `OneToMany` side. - -`*hibernate.cache.use_reference_entries*` (e.g. `true` or `false`):: -Optimizes second-level cache operation to store immutable entities (aka "reference") which do not have associations into cache directly. In this case, disassembling and deep copy operations can be avoided. The default value of this property is `false`. - -`*hibernate.classcache*` (e.g. `hibernate.classcache.org.hibernate.ejb.test.Item` = `read-write`):: -Sets the associated entity class cache concurrency strategy for the designated region. Caching configuration should follow the following pattern `hibernate.classcache. = usage[, region]` where usage is the cache strategy used and region the cache region name. - -`*hibernate.collectioncache*` (e.g. `hibernate.collectioncache.org.hibernate.ejb.test.Item.distributors` = `read-write, RegionName`):: -Sets the associated collection cache concurrency strategy for the designated region. Caching configuration should follow the following pattern `hibernate.collectioncache.. = usage[, region]` where usage is the cache strategy used and region the cache region name. - -[[configurations-infinispan]] -=== Infinispan properties - -For more details about how to customize the Infinispan second-level cache provider, check out the -https://infinispan.org/docs/stable/titles/integrating/integrating.html#configuration_properties[Infinispan User Guide]. - -[[configurations-transactions]] -=== Transactions properties - -`*hibernate.transaction.jta.platform*` (e.g. `JBossAS`, `BitronixJtaPlatform`):: -Names the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/transaction/jta/platform/spi/JtaPlatform.html[`JtaPlatform`] implementation to use for integrating with JTA systems. -Can reference either a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/transaction/jta/platform/spi/JtaPlatform.html[`JtaPlatform`] instance or the name of the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/transaction/jta/platform/spi/JtaPlatform.html[`JtaPlatform`] implementation class. - -`*hibernate.jta.prefer_user_transaction*` (e.g. `true` or `false` (default value)):: -Should we prefer using the `org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform#retrieveUserTransaction` over using `org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform#retrieveTransactionManager`? - -`*hibernate.transaction.jta.platform_resolver*`:: -Names the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/transaction/jta/platform/spi/JtaPlatformResolver.html[`JtaPlatformResolver`] implementation to use. - -`*hibernate.jta.cacheTransactionManager*` (e.g. `true` (default value) or `false`):: -A configuration value key used to indicate that it is safe to cache. - -`*hibernate.jta.cacheUserTransaction*` (e.g. `true` or `false` (default value)):: -A configuration value key used to indicate that it is safe to cache. - -`*hibernate.transaction.flush_before_completion*` (e.g. `true` or `false` (default value)):: -Causes the session be flushed during the before completion phase of the transaction. If possible, use built-in and automatic session context management instead. - -`*hibernate.transaction.auto_close_session*` (e.g. `true` or `false` (default value)):: -Causes the session to be closed during the after completion phase of the transaction. If possible, use built-in and automatic session context management instead. - -`*hibernate.transaction.coordinator_class*`:: -Names the implementation of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/resource/transaction/spi/TransactionCoordinatorBuilder.html[`TransactionCoordinatorBuilder`] to use for creating https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/resource/transaction/spi/TransactionCoordinator.html[`TransactionCoordinator`] instances. -+ -Can be a `TransactionCoordinatorBuilder` instance, `TransactionCoordinatorBuilder` implementation `Class` reference, a `TransactionCoordinatorBuilder` implementation class name (fully-qualified name) or a short name. -+ -The following short names are defined for this setting: -+ -`jdbc`::: Manages transactions via calls to `java.sql.Connection` (default for non-Jakarta Persistence applications). -`jta`::: Manages transactions via JTA. See <>. -+ - -If a Jakarta Persistence application does not provide a setting for `hibernate.transaction.coordinator_class`, Hibernate will -automatically build the proper transaction coordinator based on the transaction type for the persistence unit. -+ -If a non-Jakarta Persistence application does not provide a setting for `hibernate.transaction.coordinator_class`, Hibernate -will use `jdbc` as the default. This default will cause problems if the application actually uses JTA-based transactions. -A non-Jakarta Persistence application that uses JTA-based transactions should explicitly set `hibernate.transaction.coordinator_class=jta` -or provide a custom https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/resource/transaction/TransactionCoordinatorBuilder.html[`TransactionCoordinatorBuilder`] that builds a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/resource/transaction/TransactionCoordinator.html[`TransactionCoordinator`] that properly coordinates with JTA-based transactions. - -`*hibernate.jta.track_by_thread*` (e.g. `true` (default value) or `false`):: -A transaction can be rolled back by another thread ("tracking by thread") and not the original application. -Examples of this include a JTA transaction timeout handled by a background reaper thread. -+ -The ability to handle this situation requires checking the Thread ID every time Session is called, so enabling this can certainly have a performance impact. - -[line-through]#`*hibernate.transaction.factory_class*`#:: -+ -WARNING: This is a legacy setting that's been deprecated and you should use the `hibernate.transaction.jta.platform` instead. - -`*hibernate.jta.allowTransactionAccess*`(e.g. `true` (default value) or `false`):: -It allows access to the underlying `org.hibernate.Transaction` even when using JTA -since the Jakarta Persistence specification prohibits this behavior. -+ -If this configuration property is set to `true`, access is granted to the underlying `org.hibernate.Transaction`. -If it's set to `false`, you won't be able to access the `org.hibernate.Transaction`. -+ -The default behavior is to allow access unless the `Session` is bootstrapped via Jakarta Persistence. - -[[configurations-multi-tenancy]] -=== Multi-tenancy settings - -`*hibernate.multi_tenant_connection_provider*`:: -Names a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/connections/spi/MultiTenantConnectionProvider.html[`MultiTenantConnectionProvider`] implementation to use. As `MultiTenantConnectionProvider` is also a service, can be configured directly through the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/registry/StandardServiceRegistryBuilder.html[`StandardServiceRegistryBuilder`]. - -`*hibernate.tenant_identifier_resolver*`:: -Names a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/context/spi/CurrentTenantIdentifierResolver.html[`CurrentTenantIdentifierResolver`] implementation to resolve the current tenant identifier so that calling `SessionFactory#openSession()` would get a `Session` that's connected to the right tenant. -+ -Can be a `CurrentTenantIdentifierResolver` instance, `CurrentTenantIdentifierResolver` implementation `Class` object reference or a `CurrentTenantIdentifierResolver` implementation class name. - -`*hibernate.multi_tenant.datasource.identifier_for_any*` (e.g. `true` or `false` (default value)):: -When the `hibernate.connection.datasource` property value is resolved to a `javax.naming.Context` object, this configuration property defines the JNDI name used to locate the `DataSource` used for fetching the initial `Connection` which is used to access the database metadata of the underlying database(s) (in situations where we do not have a tenant id, like startup processing). - -[[configurations-hbmddl]] -=== Automatic schema generation - -`*hibernate.hbm2ddl.auto*` (e.g. `none` (default value), `create-only`, `drop`, `create`, `create-drop`, `validate`, and `update`):: -Setting to perform `SchemaManagementTool` actions automatically as part of the `SessionFactory` lifecycle. -Valid options are defined by the `externalHbm2ddlName` value of the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/Action.html[`Action`] enum: -+ -`none`::: No action will be performed. -`create-only`::: Database creation will be generated. -`drop`::: Database dropping will be generated. -`create`::: Database dropping will be generated followed by database creation. -`create-drop`::: Drop the schema and recreate it on SessionFactory startup. Additionally, drop the schema on SessionFactory shutdown. -`validate`::: Validate the database schema. -`update`::: Update the database schema. - -`*jakarta.persistence.schema-generation.database.action*` (e.g. `none` (default value), `create-only`, `drop`, `create`, `create-drop`, `validate`, and `update`):: -Setting to perform `SchemaManagementTool` actions automatically as part of the `SessionFactory` lifecycle. -Valid options are defined by the `externalJpaName` value of the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/Action.html[`Action`] enum: -+ -`none`::: No action will be performed. -`create`::: Database creation will be generated. -`drop`::: Database dropping will be generated. -`drop-and-create`::: Database dropping will be generated followed by database creation. - -`*jakarta.persistence.schema-generation.scripts.action*` (e.g. `none` (default value), `create-only`, `drop`, `create`, `create-drop`, `validate`, and `update`):: -Setting to perform `SchemaManagementTool` actions writing the commands into a DDL script file. -Valid options are defined by the `externalJpaName` value of the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/Action.html[`Action`] enum: -+ -`none`::: No action will be performed. -`create`::: Database creation will be generated. -`drop`::: Database dropping will be generated. -`drop-and-create`::: Database dropping will be generated followed by database creation. - -`*jakarta.persistence.schema-generation-connection*`:: -Allows passing a specific `java.sql.Connection` instance to be used by `SchemaManagementTool`. - -`*jakarta.persistence.database-product-name*`:: -Specifies the name of the database provider in cases where a Connection to the underlying database is not available (aka, mainly in generating scripts). -In such cases, a value for this setting _must_ be specified. -+ -The value of this setting is expected to match the value returned by `java.sql.DatabaseMetaData#getDatabaseProductName()` for the target database. -+ -Additionally, specifying `jakarta.persistence.database-major-version` and/or `jakarta.persistence.database-minor-version` may be required to understand exactly how to generate the required schema commands. - -`*jakarta.persistence.database-major-version*`:: -Specifies the major version of the underlying database, as would be returned by `java.sql.DatabaseMetaData#getDatabaseMajorVersion` for the target database. -+ -This value is used to help more precisely determine how to perform schema generation tasks for the underlying database in cases where `jakarta.persistence.database-product-name` does not provide enough distinction. - -`*jakarta.persistence.database-minor-version*`:: -Specifies the minor version of the underlying database, as would be returned by `java.sql.DatabaseMetaData#getDatabaseMinorVersion` for the target database. -+ -This value is used to help more precisely determine how to perform schema generation tasks for the underlying database in cases where `jakarta.persistence.database-product-name` and `jakarta.persistence.database-major-version` does not provide enough distinction. - -`*jakarta.persistence.schema-generation.create-source*`:: -Specifies whether schema generation commands for schema creation are to be determined based on object/relational mapping metadata, DDL scripts, or a combination of the two. -See https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/SourceType.html[`SourceType`] for valid set of values. -+ -If no value is specified, a default is assumed as follows: -+ -* if source scripts are specified (per `jakarta.persistence.schema-generation.create-script-source`), then `script` is assumed -* otherwise, `metadata` is assumed - -`*jakarta.persistence.schema-generation.drop-source*`:: -Specifies whether schema generation commands for schema dropping are to be determined based on object/relational mapping metadata, DDL scripts, or a combination of the two. -See https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/SourceType.html[`SourceType`] for valid set of values. -+ -If no value is specified, a default is assumed as follows: -+ -* if source scripts are specified (per `jakarta.persistence.schema-generation.drop-script-source`), then the `script` option is assumed -* otherwise, `metadata` is assumed - -`*jakarta.persistence.schema-generation.create-script-source*`:: -Specifies the `create` script file as either a `java.io.Reader` configured for reading of the DDL script file or a string designating a file `java.net.URL` for the DDL script. -+ -Hibernate historically also accepted `hibernate.hbm2ddl.import_files` for a similar purpose, but `jakarta.persistence.schema-generation.create-script-source` should be preferred over `hibernate.hbm2ddl.import_files`. - -`*jakarta.persistence.schema-generation.drop-script-source*`:: - Specifies the `drop` script file as either a `java.io.Reader` configured for reading of the DDL script file or a string designating a file `java.net.URL` for the DDL script. - -`*jakarta.persistence.schema-generation.scripts.create-target*`:: -For cases where the `jakarta.persistence.schema-generation.scripts.action` value indicates that schema creation commands should be written to DDL script file, `jakarta.persistence.schema-generation.scripts.create-target` specifies either a `java.io.Writer` configured for output of the DDL script or a string specifying the file URL for the DDL script. - -`*jakarta.persistence.schema-generation.scripts.drop-target*`:: -For cases where the `jakarta.persistence.schema-generation.scripts.action` value indicates that schema dropping commands should be written to DDL script file, `jakarta.persistence.schema-generation.scripts.drop-target` specifies either a `java.io.Writer` configured for output of the DDL script or a string specifying the file URL for the DDL script. - -`*hibernate.hbm2ddl.schema-generation.script.append*` (e.g. `true` (default value) or `false`):: -For cases where the `jakarta.persistence.schema-generation.scripts.action` value indicates that schema commands should be written to DDL script file, `hibernate.hbm2ddl.schema-generation.script.append` specifies if schema commands should be appended to the end of the file rather than written at the beginning of the file. -Values are `true` for appending schema commands to the end of the file, `false` for writing achema commands at the beginning of the file. - -`*jakarta.persistence.hibernate.hbm2ddl.import_files*` (e.g. `import.sql` (default value)):: -Comma-separated names of the optional files containing SQL DML statements executed during the `SessionFactory` creation. -File order matters, the statements of a given file are executed before the statements of the following one. -+ -These statements are only executed if the schema is created, meaning that `hibernate.hbm2ddl.auto` is set to `create`, `create-drop`, or `update`. -`jakarta.persistence.schema-generation.create-script-source` / `jakarta.persistence.schema-generation.drop-script-source` should be preferred. - -`*jakarta.persistence.sql-load-script-source*`:: -Jakarta Persistence variant of `hibernate.hbm2ddl.import_files`. Specifies a `java.io.Reader` configured for reading of the SQL load script or a string designating the file `java.net.URL` for the SQL load script. -A "SQL load script" is a script that performs some database initialization (INSERT, etc). - -`*hibernate.hbm2ddl.import_files_sql_extractor*`:: -Reference to the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/hbm2ddl/ImportSqlCommandExtractor.html[`ImportSqlCommandExtractor`] implementation class to use for parsing source/import files as defined by `jakarta.persistence.schema-generation.create-script-source`, -`jakarta.persistence.schema-generation.drop-script-source` or `hibernate.hbm2ddl.import_files`. -+ -Reference may refer to an instance, a Class implementing `ImportSqlCommandExtractor` or the fully-qualified name of the `ImportSqlCommandExtractor` implementation. -If the fully-qualified name is given, the implementation must provide a no-arg constructor. -+ -The default value is https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/hbm2ddl/SingleLineSqlCommandExtractor.html[`SingleLineSqlCommandExtractor`]. - -`*hibernate.hbm2ddl.create_namespaces*` (e.g. `true` or `false` (default value)):: -Specifies whether to automatically create the database schema/catalog also. - -`*jakarta.persistence.create-database-schemas*` (e.g. `true` or `false` (default value)):: -The Jakarta Persistence variant of `hibernate.hbm2ddl.create_namespaces`. Specifies whether the persistence provider is to create the database schema(s) in addition to creating database objects (tables, sequences, constraints, etc). -The value of this boolean property should be set to `true` if the persistence provider is to create schemas in the database or to generate DDL that contains "CREATE SCHEMA" commands. -+ -If this property is not supplied (or is explicitly `false`), the provider should not attempt to create database schemas. - -`*hibernate.hbm2ddl.schema_filter_provider*`:: -Used to specify the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/spi/SchemaFilterProvider.html[`SchemaFilterProvider`] to be used by `create`, `drop`, `migrate`, and `validate` operations on the database schema. -`SchemaFilterProvider` provides filters that can be used to limit the scope of these operations to specific namespaces, tables and sequences. All objects are included by default. - -`*hibernate.hbm2ddl.jdbc_metadata_extraction_strategy*` (e.g. `grouped` (default value) or `individually`):: -Setting to choose the strategy used to access the JDBC Metadata. -Valid options are defined by the `strategy` value of the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/JdbcMetadaAccessStrategy.html[`JdbcMetadaAccessStrategy`] enum: -+ -`grouped`::: https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/spi/SchemaMigrator.html[`SchemaMigrator`] and https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/spi/SchemaValidator.html[`SchemaValidator`] execute a single `java.sql.DatabaseMetaData#getTables(String, String, String, String[])` call to retrieve all the database table in order to determine if all the ``jakarta.persistence.Entity``s have a corresponding mapped database tables. This strategy may require `hibernate.default_schema` and/or `hibernate.default_catalog` to be provided. -`individually`::: https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/spi/SchemaMigrator.html[`SchemaMigrator`] and https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/schema/spi/SchemaValidator.html[`SchemaValidator`] execute one `java.sql.DatabaseMetaData#getTables(String, String, String, String[])` call for each `jakarta.persistence.Entity` in order to determine if a corresponding database table exists. - -`*hibernate.hbm2ddl.delimiter*` (e.g. `;`):: -Identifies the delimiter to use to separate schema management statements in script outputs. -The default value is `;`. - -`*hibernate.schema_management_tool*` (e.g. A schema name):: -Used to specify the `SchemaManagementTool` to use for performing schema management. The default is to use `HibernateSchemaManagementTool`. - -`*hibernate.synonyms*` (e.g. `true` or `false` (default value)):: -If enabled, allows schema update and validation to support synonyms. Due to the possibility that this would return duplicate tables (especially in Oracle), this is disabled by default. - -`*hibernate.hbm2ddl.extra_physical_table_types*` (e.g. `BASE TABLE`):: -Identifies a comma-separated list of values to specify extra table types, other than the default `TABLE` value, to recognize as defining a physical table by schema update, creation and validation. - -`*hibernate.hbm2ddl.default_constraint_mode*` (`CONSTRAINT` (default value) or `NO_CONSTRAINT`):: -Default `jakarta.persistence.ConstraintMode` for foreign key mapping if `PROVIDER_DEFAULT` strategy used. - -`*hibernate.schema_update.unique_constraint_strategy*` (e.g. `DROP_RECREATE_QUIETLY`, `RECREATE_QUIETLY`, `SKIP`):: -Unique columns and unique keys both use unique constraints in most dialects. -`SchemaUpdate` needs to create these constraints, but DBs support for finding existing constraints is extremely inconsistent. -Further, non-explicitly-named unique constraints use randomly generated characters. -+ -Therefore, the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/tool/hbm2ddl/UniqueConstraintSchemaUpdateStrategy.html[`UniqueConstraintSchemaUpdateStrategy`] offers the following options: -+ -`DROP_RECREATE_QUIETLY`::: Default option. -Attempt to drop, then (re-)create each unique constraint. Ignore any exceptions being thrown. -`RECREATE_QUIETLY`::: -Attempts to (re-)create unique constraints, ignoring exceptions thrown if the constraint already existed. -`SKIP`::: -Does not attempt to create unique constraints on a schema update. - -`*hibernate.hbm2ddl.charset_name*` (e.g. `Charset.defaultCharset()`):: -Defines the charset (encoding) used for all input/output schema generation resources. By default, Hibernate uses the default charset given by `Charset.defaultCharset()`. This configuration property allows you to override the default JVM setting so that you can specify which encoding is used when reading and writing schema generation resources (e.g. File, URL). - -`*hibernate.hbm2ddl.halt_on_error*` (e.g. `true` or `false` (default value)):: -Whether the schema migration tool should halt on error, therefore terminating the bootstrap process. By default, the `EntityManagerFactory` or `SessionFactory` are created even if the schema migration throws exceptions. To prevent this default behavior, set this property value to `true`. - -[[configurations-session-events]] -=== Session events - -`*hibernate.session.events.auto*`:: -Fully qualified class name implementing the `SessionEventListener` interface. - -`*hibernate.session_factory.interceptor*` (e.g. `org.hibernate.EmptyInterceptor` (default value)):: -Names an https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/Interceptor[`Interceptor`] implementation to be applied to every `Session` created by the current `org.hibernate.SessionFactory`. -+ -Can reference: -+ -* `Interceptor` instance -* `Interceptor` implementation `Class` object reference -* `Interceptor` implementation class name - -[line-through]#`*hibernate.ejb.interceptor*`# (e.g. `hibernate.session_factory.interceptor` (default value)):: -+ -WARNING: Deprecated setting. Use `hibernate.session_factory.session_scoped_interceptor` instead. - -`*hibernate.session_factory.session_scoped_interceptor*` (e.g. fully-qualified class name or class reference):: -Names an `org.hibernate.Interceptor` implementation to be applied to the `org.hibernate.SessionFactory` and propagated to each `Session` created from the `SessionFactory`. -+ -This setting identifies an `Interceptor` implementation that is to be applied to every `Session` opened from the `SessionFactory`, -but unlike `hibernate.session_factory.interceptor`, a unique instance of the `Interceptor` is -used for each `Session`. -+ -Can reference: -+ -* `Interceptor` instance -* `Interceptor` implementation `Class` object reference -* `java.util.function.Supplier` instance which is used to retrieve the `Interceptor` instance -+ -NOTE: Specifically, this setting cannot name an `Interceptor` instance. - -[line-through]#`*hibernate.ejb.interceptor.session_scoped*`# (e.g. fully-qualified class name or class reference):: -+ -WARNING: Deprecated setting. Use `hibernate.session_factory.session_scoped_interceptor` instead. -+ -An optional Hibernate interceptor. -+ -The interceptor instance is specific to a given Session instance (and hence is not thread-safe) has to implement `org.hibernate.Interceptor` and have a no-arg constructor. -+ -This property cannot be combined with `hibernate.ejb.interceptor`. - -`*hibernate.ejb.session_factory_observer*` (e.g. fully-qualified class name or class reference):: -Specifies a `SessionFactoryObserver` to be applied to the SessionFactory. The class must have a no-arg constructor. - -`*hibernate.ejb.event*` (e.g. `hibernate.ejb.event.pre-load` = `com.acme.SecurityListener,com.acme.AuditListener`):: -Event listener list for a given event type. The list of event listeners is a comma separated fully qualified class name list. - -[[configurations-classloader]] -=== ClassLoaders property - -`*hibernate.classLoaders*`:: -Used to define a `java.util.Collection` or the `ClassLoader` instance Hibernate should use for class-loading and resource-lookups. - -[[configurations-bootstrap]] -=== Bootstrap properties - -`*hibernate.integrator_provider*` (e.g. The fully qualified name of an https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/jpa/boot/spi/IntegratorProvider.html[`IntegratorProvider`]):: -Used to define a list of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/integrator/spi/Integrator.html[`Integrator`] which is used during the bootstrap process to integrate various services. - -`*hibernate.strategy_registration_provider*` (e.g. The fully qualified name of an https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/jpa/boot/spi/StrategyRegistrationProviderList.html[`StrategyRegistrationProviderList`]):: -Used to define a list of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/registry/selector/StrategyRegistrationProvider.html[`StrategyRegistrationProvider`] which is used during the bootstrap process to provide registrations of strategy selector(s). - -`*hibernate.type_contributors*` (e.g. The fully qualified name of an https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/jpa/boot/spi/TypeContributorList.html[`TypeContributorList`]):: -Used to define a list of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/model/TypeContributor.html[`TypeContributor`] which is used during the bootstrap process to contribute types. - -`*hibernate.persister.resolver*` (e.g. The fully qualified name of a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/spi/PersisterClassResolver.html[`PersisterClassResolver`] or a `PersisterClassResolver` instance):: -Used to define an implementation of the `PersisterClassResolver` interface which can be used to customize how an entity or a collection is being persisted. - -`*hibernate.persister.factory*` (e.g. The fully qualified name of a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/spi/PersisterFactory.html[`PersisterFactory`] or a `PersisterFactory` instance):: -Like a `PersisterClassResolver`, the `PersisterFactory` can be used to customize how an entity or a collection are being persisted. - -`*hibernate.service.allow_crawling*` (e.g. `true` (default value) or `false`):: -Crawl all available service bindings for an alternate registration of a given Hibernate `Service`. - -`*hibernate.metadata_builder_contributor*` (e.g. The instance, the class or the fully qualified class name of a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/spi/MetadataBuilderContributor.html[`MetadataBuilderContributor`]):: -Used to define an instance, the class or the fully qualified class name of a https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/boot/spi/MetadataBuilderContributor.html[`MetadataBuilderContributor`] which can be used to configure the `MetadataBuilder` when bootstrapping via the Jakarta Persistence `EntityManagerFactory`. - -[[configurations-misc]] -=== Miscellaneous properties - -`*hibernate.dialect_resolvers*`:: -Names any additional https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/dialect/spi/DialectResolver.html[`DialectResolver`] implementations to register with the standard https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/engine/jdbc/dialect/spi/DialectFactory.html[`DialectFactory`]. - -`*hibernate.session_factory_name*` (e.g. A JNDI name):: -Setting used to name the Hibernate `SessionFactory`. -Naming the `SessionFactory` allows for it to be properly serialized across JVMs as long as the same name is used on each JVM. -+ -If `hibernate.session_factory_name_is_jndi` is set to `true`, this is also the name under which the `SessionFactory` is bound into JNDI on startup and from which it can be obtained from JNDI. - -`*hibernate.session_factory_name_is_jndi*` (e.g. `true` (default value) or `false`):: -Does the value defined by `hibernate.session_factory_name` represent a JNDI namespace into which the `org.hibernate.SessionFactory` should be bound and made accessible? -+ -Defaults to `true` for backward compatibility. Set this to `false` if naming a SessionFactory is needed for serialization purposes, but no writable JNDI context exists in the runtime environment or if the user simply does not want JNDI to be used. - -`*hibernate.ejb.entitymanager_factory_name*` (e.g. By default, the persistence unit name is used, otherwise a randomly generated UUID):: -Internally, Hibernate keeps track of all `EntityManagerFactory` instances using the `EntityManagerFactoryRegistry`. The name is used as a key to identify a given `EntityManagerFactory` reference. - -`*hibernate.ejb.cfgfile*` (e.g. `hibernate.cfg.xml` (default value)):: -XML configuration file to use to configure Hibernate. - -`*hibernate.ejb.discard_pc_on_close*` (e.g. `true` or `false` (default value)):: -If true, the persistence context will be discarded (think `clear()` when the method is called). -Otherwise, the persistence context will stay alive till the transaction completion: all objects will remain managed, and any change will be synchronized with the database (default to false, ie wait for transaction completion). - -`*hibernate.ejb.metamodel.population*` (e.g. `enabled` or `disabled`, or `ignoreUnsupported` (default value)):: -Setting that indicates whether to build the Jakarta Persistence types. -+ -Accepts three values: -+ -enabled::: Do the build. -disabled::: Do not do the build. -ignoreUnsupported::: Do the build, but ignore any non-Jakarta Persistence features that would otherwise result in a failure (e.g. `@Any` annotation). - -`*hibernate.jpa.static_metamodel.population*` (e.g. `enabled` or `disabled`, or `skipUnsupported` (default value)):: -Setting that controls whether we seek out Jakarta Persistence _static metamodel_ classes and populate them. -+ -Accepts three values: -+ -enabled::: Do the population. -disabled::: Do not do the population. -skipUnsupported::: Do the population, but ignore any non-Jakarta Persistence features that would otherwise result in the population failing (e.g. `@Any` annotation). - -`*hibernate.delay_cdi_access*` (e.g. `true` or `false` (default value)):: -Defines delayed access to CDI `BeanManager`. Starting in 5.1 the preferred means for CDI bootstrapping is through https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/jpa/event/spi/jpa/ExtendedBeanManager.html[`ExtendedBeanManager`]. - -`*hibernate.resource.beans.container*` (e.g. fully-qualified class name):: -Identifies an explicit `org.hibernate.resource.beans.container.spi.BeanContainer` to be used. -+ -Note that, for CDI-based containers, setting this is not necessary. -Simply pass the `BeanManager` to use via `jakarta.persistence.bean.manager` and optionally specify `hibernate.delay_cdi_access`. -+ -This setting is more meant to integrate non-CDI bean containers such as Spring. - -`*hibernate.allow_update_outside_transaction*` (e.g. `true` or `false` (default value)):: -Setting that allows to perform update operations outside of a transaction boundary. -+ -Accepts two values: -+ -true::: allows to flush an update out of a transaction -false::: does not allow - -`*hibernate.collection_join_subquery*` (e.g. `true` (default value) or `false`):: -Setting which indicates whether or not the new JOINs over collection tables should be rewritten to subqueries. - -`*hibernate.allow_refresh_detached_entity*` (e.g. `true` (default value when using Hibernate native bootstrapping) or `false` (default value when using Jakarta Persistence bootstrapping)):: -Setting that allows to call `jakarta.persistence.EntityManager#refresh(entity)` or `Session#refresh(entity)` on a detached instance even when the `org.hibernate.Session` is obtained from a Jakarta Persistence `jakarta.persistence.EntityManager`. - -`*hibernate.use_entity_where_clause_for_collections*` (e.g., `true` (default) or `false`):: -Setting controls whether an entity's "where" clause, mapped using `@Where(clause = "...")` or `` is taken into account when loading one-to-many or many-to-many collections of that type of entity. - -`*hibernate.event.merge.entity_copy_observer*` (e.g. `disallow` (default value), `allow`, `log` (testing purpose only) or fully-qualified class name):: -Setting that specifies how Hibernate will respond when multiple representations of the same persistent entity ("entity copy") is detected while merging. -+ -The possible values are: -+ -disallow::: throws `IllegalStateException` if an entity copy is detected -allow::: performs the merge operation on each entity copy that is detected -log::: (provided for testing only) performs the merge operation on each entity copy that is detected and logs information about the entity copies. -This setting requires DEBUG logging be enabled for https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/event/internal/EntityCopyAllowedLoggedObserver.html[`EntityCopyAllowedLoggedObserver`]. - -In addition, the application may customize the behavior by providing an implementation of https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/event/spi/EntityCopyObserver.html[`EntityCopyObserver`] and setting `hibernate.event.merge.entity_copy_observer` to the class name. -When this property is set to `allow` or `log`, Hibernate will merge each entity copy detected while cascading the merge operation. -In the process of merging each entity copy, Hibernate will cascade the merge operation from each entity copy to its associations with `cascade = CascadeType.MERGE` or `cascade = CascadeType.ALL`. -The entity state resulting from merging an entity copy will be overwritten when another entity copy is merged. - -For more details, check out the <> section. - -[[configurations-envers]] -=== Envers properties - -`*hibernate.envers.autoRegisterListeners*` (e.g. `true` (default value) or `false`):: -When set to `false`, the Envers entity listeners are no longer auto-registered, so you need to register them manually during the bootstrap process. - -`*hibernate.integration.envers.enabled*` (e.g. `true` (default value) or `false`):: -Enable or disable the Hibernate Envers `Service` integration. - -`*hibernate.listeners.envers.autoRegister*`:: -Legacy setting. Use `hibernate.envers.autoRegisterListeners` or `hibernate.integration.envers.enabled` instead. - -[[configurations-spatial]] -=== Spatial properties - -`*hibernate.integration.spatial.enabled*` (e.g. `true` (default value) or `false`):: -Enable or disable the Hibernate Spatial `Service` integration. - -`*hibernate.spatial.connection_finder*` (e.g. `org.geolatte.geom.codec.db.oracle.DefaultConnectionFinder`):: -Define the fully-qualified name of class implementing the `org.geolatte.geom.codec.db.oracle.ConnectionFinder` interface. - -[[configurations-internal]] -=== Internal properties - -The following configuration properties are used internally, and you shouldn't probably have to configured them in your application. - -`*hibernate.enable_specj_proprietary_syntax*` (e.g. `true` or `false` (default value)):: -Enable or disable the SpecJ proprietary mapping syntax which differs from Jakarta Persistence specification. Used during performance testing only. - -`*hibernate.temp.use_jdbc_metadata_defaults*` (e.g. `true` (default value) or `false`):: -This setting is used to control whether we should consult the JDBC metadata to determine certain Settings default values when the database may not be available (mainly in tools usage). - -`*hibernate.connection_provider.injection_data*`:: -Connection provider settings to be injected (a `Map` instance) in the currently configured connection provider. - -`*hibernate.jandex_index*`:: -Names a Jandex `org.jboss.jandex.Index` instance to use. diff --git a/documentation/src/main/asciidoc/userguide/appendices/LegacyBasicTypeResolution.adoc b/documentation/src/main/asciidoc/userguide/appendices/LegacyBasicTypeResolution.adoc index 81ed431616..273be37a5a 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/LegacyBasicTypeResolution.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/LegacyBasicTypeResolution.adoc @@ -4,6 +4,7 @@ :extrasdir: extras :originalextrasdir: ../chapters/domain/extras +[appendix] [[basic-legacy]] == Legacy BasicType resolution diff --git a/documentation/src/main/asciidoc/userguide/appendices/Legacy_DomainModel.adoc b/documentation/src/main/asciidoc/userguide/appendices/Legacy_DomainModel.adoc deleted file mode 100644 index 43f92dc654..0000000000 --- a/documentation/src/main/asciidoc/userguide/appendices/Legacy_DomainModel.adoc +++ /dev/null @@ -1,49 +0,0 @@ -[[appendix-legacy-domain-model]] -== Legacy Domain Model -:sourcedir: extras - -.Declaring a version property in `hbm.xml` -==== -[source,xml] ----- -include::{sourcedir}/version_property.xml[] ----- -==== - -[cols=",",] -|======================================================================= -|column |The name of the column holding the version number. Optional, defaults to the property name. -|name |The name of a property of the persistent class. -|type |The type of the version number. Optional, defaults to `integer`. -|access |Hibernate's strategy for accessing the property value. Optional, defaults to `property`. -|unsaved-value |Indicates that an instance is newly instantiated and thus unsaved. -This distinguishes it from detached instances that were saved or loaded in a previous session. -The default value, `undefined`, indicates that the identifier property value should be used. Optional. -|generated |Indicates that the version property value is generated by the database. Optional, defaults to `never`. -|insert |Whether or not to include the `version` column in SQL `insert` statements. -Defaults to `true`, but you can set it to `false` if the database column is defined with a default value of `0`. -|======================================================================= - -.The timestamp element in `hbm.xml` -==== -[source,xml] ----- -include::{sourcedir}/timestamp_version.xml[] ----- -==== - -[cols=",",] -|======================================================================= -|column |The name of the column which holds the timestamp. Optional, defaults to the property name -|name |The name of a JavaBeans style property of Java type `Date` or `Timestamp` of the persistent class. -|access |The strategy Hibernate uses to access the property value. Optional, defaults to `property`. -|unsaved-value |A version property which indicates that the instance is newly instantiated and unsaved. -This distinguishes it from detached instances that were saved or loaded in a previous session. -The default value of `undefined` indicates that Hibernate uses the identifier property value. -|source |Whether Hibernate retrieves the timestamp from the database or the current JVM. -Database-based timestamps incur an overhead because Hibernate needs to query the database each time to determine the incremental next value. -However, database-derived timestamps are safer to use in a clustered environment. -Not all database dialects are known to support the retrieval of the database's current timestamp. -Others may also be unsafe for locking because of lack of precision. -|generated |Whether the timestamp property value is generated by the database. Optional, defaults to `never`. -|======================================================================= \ No newline at end of file diff --git a/documentation/src/main/asciidoc/userguide/appendices/Legacy_Native_Queries.adoc b/documentation/src/main/asciidoc/userguide/appendices/Legacy_Native_Queries.adoc index af1962e196..ea446867c7 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/Legacy_Native_Queries.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/Legacy_Native_Queries.adoc @@ -1,3 +1,4 @@ +[appendix] [[appendix-legacy-native-queries]] == Legacy Hibernate Native Queries diff --git a/documentation/src/main/asciidoc/userguide/appendices/SettingsReference.adoc b/documentation/src/main/asciidoc/userguide/appendices/SettingsReference.adoc new file mode 100644 index 0000000000..f7622db9f2 --- /dev/null +++ b/documentation/src/main/asciidoc/userguide/appendices/SettingsReference.adoc @@ -0,0 +1,27 @@ +[appendix] +[[settings]] +== Configuration Settings + +Configuration settings can be broadly broken down into 3 categories - + +Jakarta Persistence:: + Settings which are standardized by the Jakarta Persistence specification for configuring any persistence provider. These + settings are defined by the `jakarta.persistence.` namespace +Hibernate:: + Hibernate-specific settings which control various Hibernate behaviors which are extensions to or outside the scope + of the Jakarta Persistence specification. These settings are defined by the `hibernate.` namespace +Legacy JPA:: + Settings which were standardized by Java Persistence, the legacy version of the Jakarta Persistence specification + (prior to version 3.1). These settings are defined by the `javax.persistence.` namespace + +[NOTE] +==== +For the time being, Hibernate continues to support the legacy Java Persistence settings in addition to +the Jakarta Persistence forms. Applications should strongly consider migrating to the new Jakarta Persistence +as support for the legacy Java Persistence will likely be removed at some point. + +For (legacy) Hibernate settings which have a direct Jakarta Persistence corollary, the Jakarta Persistence +form should be preferred - e.g. `hibernate.connection.driver_class` -> `jakarta.persistence.jdbc.driver`. +==== + +include::../../../../../target/asciidoc/fragments/config-settings.adoc[] diff --git a/documentation/src/main/asciidoc/userguide/chapters/bootstrap/Bootstrap.adoc b/documentation/src/main/asciidoc/userguide/chapters/bootstrap/Bootstrap.adoc index ad8eca6195..53d17d1f0a 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/bootstrap/Bootstrap.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/bootstrap/Bootstrap.adoc @@ -13,7 +13,7 @@ The process is very different for each. [TIP] ==== -During the bootstrap process, you might want to customize Hibernate behavior so make sure you check the <> section as well. +During the bootstrap process, you might want to customize Hibernate behavior so make sure you check the <> section as well. ==== [[bootstrap-native]] diff --git a/documentation/src/main/asciidoc/userguide/chapters/events/Events.adoc b/documentation/src/main/asciidoc/userguide/chapters/events/Events.adoc index 668e0f3ccf..e8b9c8e638 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/events/Events.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/events/Events.adoc @@ -1,5 +1,5 @@ [[events]] -== Interceptors and events +== Interceptors and Events :root-project-dir: ../../../../../../.. :core-project-dir: {root-project-dir}/hibernate-core :example-dir-event: {core-project-dir}/src/test/java/org/hibernate/orm/test/events diff --git a/documentation/src/main/asciidoc/userguide/chapters/jdbc/Database_Access.adoc b/documentation/src/main/asciidoc/userguide/chapters/jdbc/Database_Access.adoc index 6f6951ae5a..a12ee7d7c9 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/jdbc/Database_Access.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/jdbc/Database_Access.adoc @@ -1,5 +1,5 @@ [[database]] -== Database access +== Database Access [[database-connectionprovider]] === ConnectionProvider diff --git a/documentation/src/main/asciidoc/userguide/chapters/jndi/JNDI.adoc b/documentation/src/main/asciidoc/userguide/chapters/jndi/JNDI.adoc index 8be0104251..ccc3b453da 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/jndi/JNDI.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/jndi/JNDI.adoc @@ -12,8 +12,8 @@ Generally, it does this when the application: All of these JNDI calls route through a single service whose role is `org.hibernate.engine.jndi.spi.JndiService`. The standard `JndiService` accepts a number of configuration settings: -`hibernate.jndi.class`:: names the `javax.naming.InitialContext` implementation class to use. See https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[`javax.naming.Context#INITIAL_CONTEXT_FACTORY`] -`hibernate.jndi.url`:: names the JNDI InitialContext connection url. See https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#PROVIDER_URL[`javax.naming.Context.PROVIDER_URL`] +* <> +* <> Any other settings prefixed with `hibernate.jndi.` will be collected and passed along to the JNDI provider. diff --git a/documentation/src/main/asciidoc/userguide/chapters/schema/Schema.adoc b/documentation/src/main/asciidoc/userguide/chapters/schema/Schema.adoc index e4d61f066c..184972fe03 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/schema/Schema.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/schema/Schema.adoc @@ -1,5 +1,5 @@ [[schema-generation]] -== Schema generation +== Schema Generation :root-project-dir: ../../../../../../.. :core-project-dir: {root-project-dir}/hibernate-core :example-dir-schemagen: {core-project-dir}/src/test/java/org/hibernate/orm/test/schema diff --git a/documentation/src/main/asciidoc/userguide/chapters/transactions/Transactions.adoc b/documentation/src/main/asciidoc/userguide/chapters/transactions/Transactions.adoc index b4940e7315..028d770c75 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/transactions/Transactions.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/transactions/Transactions.adoc @@ -1,5 +1,5 @@ [[transactions]] -== Transactions and concurrency control +== Transactions :root-project-dir: ../../../../../../.. :core-project-dir: {root-project-dir}/hibernate-core :example-dir-transaction: {core-project-dir}/src/test/java/org/hibernate/orm/test/transactions diff --git a/documentation/src/javadoc/overview.html b/documentation/src/main/javadoc/overview.html similarity index 99% rename from documentation/src/javadoc/overview.html rename to documentation/src/main/javadoc/overview.html index 0cdf87796e..49ca4f6153 100644 --- a/documentation/src/javadoc/overview.html +++ b/documentation/src/main/javadoc/overview.html @@ -6,7 +6,7 @@ --> -

Hibernate ORM aggregated API documentation

+

Hibernate ORM Javadocs

Hibernate is a library for object/relation mapping (ORM). It provides: diff --git a/documentation/src/javadoc/stylesheet.css b/documentation/src/main/javadoc/stylesheet.css similarity index 100% rename from documentation/src/javadoc/stylesheet.css rename to documentation/src/main/javadoc/stylesheet.css diff --git a/documentation/status.md b/documentation/status.md deleted file mode 100644 index f7f2b0ec68..0000000000 --- a/documentation/status.md +++ /dev/null @@ -1,83 +0,0 @@ -Status of the documentation overhaul (5.0 version) -================================================== - -Overall the plan is to define 3 DocBook-based guides. The intention is for this document to serve -as an outline of the work and a status of what still needs done. - -NOTE : entries marked with strike-through indicate that the content is believed to be done; review -would still be appreciated. - - -User Guide -========== - -Covers reference topics targeting users. - -* Prefix -* Architecture -* DomainModel -* Bootstrap -* PersistenceContext -* Database_Access -* Transactions -* JNDI -* Fetching - still need to document batch fetching, subselect fetching, extra laziness and EntityGraphs -* Flushing (to be written) -* Cascading (needs lots of work) -* Locking (needs some work) -* Batching (needs lot of work - not started - open questions) -* Caching (needs some work) -* Events (need some work) -* Query - HQL/JPQL -* Query - Criteria -* Query - Native (copy from old) -* Multi_Tenancy (needs some work) -* OSGi (right place for this?) -* Envers (right place for this?) -* Portability (needs some work) - - -Domain Model Mapping Guide -=========================== - -Covers mapping domain model to database. Note that a lot of the "not started" content exists elsewhere; its merely a -matter of pulling that content in and better organizing it. - - -* Prefix -* Data_Categorizations -* Entity (needs some work) -* Basic_Types -* Composition -* Collection (needs some work) -* Identifiers (mostly done - needs "derived id" stuff documented) -* Natural_Id -* Secondary_Tables (not started) - logically a joined in-line view -* Associations (not started) -* Attribute_Access (not started) -* Mapping_Overrides - AttributeOverrides/AssociationOverrides (not started) -* Generated_attributes (not started) -* "columns, formulas, read/write-fragments" (not started) -* Naming_Strategies - implicit, physical, quoting (not started) -* Database_Constraints - pk, fk, uk, check, etc (not started) -* Auxiliary_DB_Objects - does this belong here? or somewhere else (integrations guide) discussing schema tooling? - - -Integrations Guide -=================== - -* Services&Registries (pretty much done) -* IdGeneratorStrategyInterpreter (not started) -* custom Session/SessionFactory implementors (not started) -* ??? - - -Overall -======= - -* I really like the idea of each chapter having a title+abstract. See userGuide/chapters/HQL.xml - for an example. -* I really like the idea of each chapter having a "Related Topics" (?)sidebar(?). See - userGuide/chapters/HQL.xml for an example. I am not sure `` is the best element for - this concept, but I could not find a better one on cursory glance. I noticed `literallayout` used in - a few DocBook examples for something similar. diff --git a/gradle/javadoc.gradle b/gradle/javadoc.gradle index c1257077d0..466e480a98 100644 --- a/gradle/javadoc.gradle +++ b/gradle/javadoc.gradle @@ -25,24 +25,30 @@ javadoc { // Travis CI JDK 11 build did not like this // docletpath = configurations.asciidoclet.files.asType(List) // doclet = 'org.asciidoctor.Asciidoclet' + overview = 'src/main/javadoc/overview.html' + stylesheetFile = project.file( 'src/main/javadoc/stylesheet.css' ) windowTitle = "$project.name JavaDocs" docTitle = "$project.name JavaDocs ($project.version)" bottom = "Copyright © 2001-$currentYear Red Hat, Inc. All Rights Reserved." use = true encoding = 'UTF-8' - links += [ + + links = [ 'https://docs.oracle.com/en/java/javase/11/docs/api/', - 'https://jakarta.ee/specifications/platform/9/apidocs/' + 'https://jakarta.ee/specifications/bean-validation/3.0/apidocs/', + 'https://jakarta.ee/specifications/cdi/4.0/apidocs/', + 'https://jakarta.ee/specifications/platform/9/apidocs/', + 'https://www.javadoc.io/doc/javax.cache/cache-api/1.0.0/' ] - tags = [ "apiNote", 'implSpec', 'implNote', 'todo' ] addStringOption( 'Xdoclint:none', '-quiet' ) tags( - 'todo:X"', - 'apiNote:a:"API Note:"', - 'implSpec:a:"Implementation Specification:"', - 'implNote:a:"Implementation Note:"' + 'todo:X', + 'apiNote:a:API Note:', + 'implSpec:a:Implementation Specification:', + 'implNote:a:Implementation Note:', + 'settingDefault:f:Default Value:' ) } } diff --git a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java index a08ca889f2..8035bd2718 100644 --- a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java +++ b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java @@ -18,7 +18,8 @@ import com.mchange.v2.c3p0.DataSources; import org.hibernate.HibernateException; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; -import org.hibernate.cfg.Environment; +import org.hibernate.cfg.C3p0Settings; +import org.hibernate.cfg.JdbcSettings; import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.internal.util.PropertiesHelper; @@ -31,6 +32,7 @@ import org.hibernate.service.spi.Stoppable; import static org.hibernate.c3p0.internal.C3P0MessageLogger.C3P0_LOGGER; import static org.hibernate.c3p0.internal.C3P0MessageLogger.C3P0_MSG_LOGGER; +import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.extractSetting; /** * A connection provider that uses a C3P0 connection pool. Hibernate will use this by @@ -41,6 +43,7 @@ import static org.hibernate.c3p0.internal.C3P0MessageLogger.C3P0_MSG_LOGGER; */ public class C3P0ConnectionProvider implements ConnectionProvider, Configurable, Stoppable, ServiceRegistryAwareService { + private static volatile String HIBERNATE_STYLE_SETTING_PREFIX = C3p0Settings.C3P0_CONFIG_PREFIX + "."; //swaldman 2006-08-28: define c3p0-style configuration parameters for properties with // hibernate-specific overrides to detect and warn about conflicting @@ -104,18 +107,28 @@ public class C3P0ConnectionProvider @Override public void configure(Map props) { - final String jdbcDriverClass = (String) props.get( Environment.DRIVER ); - final String jdbcUrl = (String) props.get( Environment.URL ); + final String jdbcDriverClass = extractSetting( + props, + JdbcSettings.JAKARTA_JDBC_DRIVER, + JdbcSettings.DRIVER, + JdbcSettings.JPA_JDBC_DRIVER + ); + final String jdbcUrl = extractSetting( + props, + JdbcSettings.JAKARTA_JDBC_URL, + JdbcSettings.URL, + JdbcSettings.JPA_JDBC_URL + ); final Properties connectionProps = ConnectionProviderInitiator.getConnectionProperties( props ); C3P0_MSG_LOGGER.c3p0UsingDriver( jdbcDriverClass, jdbcUrl ); C3P0_MSG_LOGGER.connectionProperties( ConfigurationHelper.maskOut( connectionProps, "password" ) ); - autocommit = ConfigurationHelper.getBoolean( Environment.AUTOCOMMIT, props ); + autocommit = ConfigurationHelper.getBoolean( JdbcSettings.AUTOCOMMIT, props ); C3P0_MSG_LOGGER.autoCommitMode( autocommit ); if ( jdbcDriverClass == null ) { - C3P0_MSG_LOGGER.jdbcDriverNotSpecified( Environment.DRIVER ); + C3P0_MSG_LOGGER.jdbcDriverNotSpecified(); } else { try { @@ -129,20 +142,20 @@ public class C3P0ConnectionProvider try { //swaldman 2004-02-07: modify to allow null values to signify fall through to c3p0 PoolConfig defaults - final Integer minPoolSize = ConfigurationHelper.getInteger( Environment.C3P0_MIN_SIZE, props ); - final Integer maxPoolSize = ConfigurationHelper.getInteger( Environment.C3P0_MAX_SIZE, props ); - final Integer maxIdleTime = ConfigurationHelper.getInteger( Environment.C3P0_TIMEOUT, props ); - final Integer maxStatements = ConfigurationHelper.getInteger( Environment.C3P0_MAX_STATEMENTS, props ); - final Integer acquireIncrement = ConfigurationHelper.getInteger( Environment.C3P0_ACQUIRE_INCREMENT, props ); - final Integer idleTestPeriod = ConfigurationHelper.getInteger( Environment.C3P0_IDLE_TEST_PERIOD, props ); + final Integer minPoolSize = ConfigurationHelper.getInteger( C3p0Settings.C3P0_MIN_SIZE, props ); + final Integer maxPoolSize = ConfigurationHelper.getInteger( C3p0Settings.C3P0_MAX_SIZE, props ); + final Integer maxIdleTime = ConfigurationHelper.getInteger( C3p0Settings.C3P0_TIMEOUT, props ); + final Integer maxStatements = ConfigurationHelper.getInteger( C3p0Settings.C3P0_MAX_STATEMENTS, props ); + final Integer acquireIncrement = ConfigurationHelper.getInteger( C3p0Settings.C3P0_ACQUIRE_INCREMENT, props ); + final Integer idleTestPeriod = ConfigurationHelper.getInteger( C3p0Settings.C3P0_IDLE_TEST_PERIOD, props ); final Properties c3props = new Properties(); // turn hibernate.c3p0.* into c3p0.*, so c3p0 // gets a chance to see all hibernate.c3p0.* for ( String key : props.keySet() ) { - if ( key.startsWith( "hibernate.c3p0." ) ) { - final String newKey = key.substring( 15 ); + if ( key.startsWith( HIBERNATE_STYLE_SETTING_PREFIX ) ) { + final String newKey = key.substring( HIBERNATE_STYLE_SETTING_PREFIX.length() ); if ( props.containsKey( newKey ) ) { warnPropertyConflict( key, newKey ); } @@ -150,17 +163,13 @@ public class C3P0ConnectionProvider } } - setOverwriteProperty( Environment.C3P0_MIN_SIZE, C3P0_STYLE_MIN_POOL_SIZE, props, c3props, minPoolSize ); - setOverwriteProperty( Environment.C3P0_MAX_SIZE, C3P0_STYLE_MAX_POOL_SIZE, props, c3props, maxPoolSize ); - setOverwriteProperty( Environment.C3P0_TIMEOUT, C3P0_STYLE_MAX_IDLE_TIME, props, c3props, maxIdleTime ); + setOverwriteProperty( C3p0Settings.C3P0_MIN_SIZE, C3P0_STYLE_MIN_POOL_SIZE, props, c3props, minPoolSize ); + setOverwriteProperty( C3p0Settings.C3P0_MAX_SIZE, C3P0_STYLE_MAX_POOL_SIZE, props, c3props, maxPoolSize ); + setOverwriteProperty( C3p0Settings.C3P0_TIMEOUT, C3P0_STYLE_MAX_IDLE_TIME, props, c3props, maxIdleTime ); + setOverwriteProperty( C3p0Settings.C3P0_MAX_STATEMENTS, C3P0_STYLE_MAX_STATEMENTS, props, c3props, maxStatements ); + setOverwriteProperty( C3p0Settings.C3P0_ACQUIRE_INCREMENT, C3P0_STYLE_ACQUIRE_INCREMENT, props, c3props, acquireIncrement ); setOverwriteProperty( - Environment.C3P0_MAX_STATEMENTS, C3P0_STYLE_MAX_STATEMENTS, props, c3props, maxStatements - ); - setOverwriteProperty( - Environment.C3P0_ACQUIRE_INCREMENT, C3P0_STYLE_ACQUIRE_INCREMENT, props, c3props, acquireIncrement - ); - setOverwriteProperty( - Environment.C3P0_IDLE_TEST_PERIOD, + C3p0Settings.C3P0_IDLE_TEST_PERIOD, C3P0_STYLE_IDLE_CONNECTION_TEST_PERIOD, props, c3props, diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java b/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java index 8aadcfe726..dea37e50c5 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java @@ -59,6 +59,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; public @interface BatchSize { /** * The maximum batch size, a strictly positive integer. + *

+ * Default is defined by {@link org.hibernate.cfg.FetchSettings#DEFAULT_BATCH_FETCH_SIZE} */ int size(); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeProviderInitiator.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeProviderInitiator.java index 9b055d6a92..243852abaf 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeProviderInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/BytecodeProviderInitiator.java @@ -17,7 +17,7 @@ import org.hibernate.service.spi.ServiceRegistryImplementor; import org.jboss.logging.Logger; -import static org.hibernate.cfg.AvailableSettings.BYTECODE_PROVIDER; +import static org.hibernate.cfg.BytecodeSettings.BYTECODE_PROVIDER; public final class BytecodeProviderInitiator implements StandardServiceInitiator { diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java index 787b6fbe90..d5088c0424 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java @@ -70,8 +70,8 @@ import net.bytebuddy.matcher.ElementMatchers; import org.checkerframework.checker.nullness.qual.Nullable; public class BytecodeProviderImpl implements BytecodeProvider { - private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BytecodeProviderImpl.class ); + private static final String INSTANTIATOR_PROXY_NAMING_SUFFIX = "HibernateInstantiator"; private static final String OPTIMIZER_PROXY_NAMING_SUFFIX = "HibernateAccessOptimizer"; private static final ElementMatcher.Junction newInstanceMethodName = ElementMatchers.named( diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/none/BytecodeProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/none/BytecodeProviderImpl.java index ebb6eb5985..bcf13687ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/none/BytecodeProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/none/BytecodeProviderImpl.java @@ -14,7 +14,6 @@ import org.hibernate.bytecode.enhance.spi.Enhancer; import org.hibernate.bytecode.spi.BytecodeProvider; import org.hibernate.bytecode.spi.ProxyFactoryFactory; import org.hibernate.bytecode.spi.ReflectionOptimizer; -import org.hibernate.cfg.AvailableSettings; import org.hibernate.property.access.spi.PropertyAccess; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java index 5be8ff3eb3..9cd16998d5 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java @@ -6,36 +6,9 @@ */ package org.hibernate.cfg; -import java.util.Calendar; -import java.util.function.Supplier; - import org.hibernate.CustomEntityDirtinessStrategy; -import org.hibernate.Incubating; -import org.hibernate.Interceptor; -import org.hibernate.Remove; -import org.hibernate.SessionFactoryObserver; -import org.hibernate.boot.registry.selector.spi.StrategySelector; -import org.hibernate.cache.internal.NoCachingRegionFactory; -import org.hibernate.cache.spi.TimestampsCacheFactory; -import org.hibernate.context.spi.CurrentTenantIdentifierResolver; -import org.hibernate.engine.jdbc.batch.spi.BatchBuilder; -import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy; import org.hibernate.jpa.LegacySpecHints; import org.hibernate.jpa.SpecHints; -import org.hibernate.query.spi.QueryPlan; -import org.hibernate.query.NullPrecedence; -import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableStrategy; -import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableStrategy; -import org.hibernate.query.sqm.mutation.internal.temptable.PersistentTableStrategy; -import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; -import org.hibernate.resource.jdbc.spi.StatementInspector; -import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; -import org.hibernate.type.WrapperArrayHandling; -import org.hibernate.type.format.FormatMapper; - -import jakarta.persistence.criteria.CriteriaDelete; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.CriteriaUpdate; /** * Enumerates the configuration properties supported by Hibernate, including @@ -56,172 +29,15 @@ import jakarta.persistence.criteria.CriteriaUpdate; * * @author Steve Ebersole */ -public interface AvailableSettings { +public interface AvailableSettings + extends BatchSettings, BytecodeSettings, CacheSettings, EnvironmentSettings, FetchSettings, + JdbcSettings, JpaComplianceSettings, ManagedBeanSettings, MappingSettings, MultiTenancySettings, + PersistenceSettings, QuerySettings, SchemaToolingSettings, SessionEventSettings, StatisticsSettings, + TransactionSettings, ValidationSettings { - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Jakarta Persistence defined settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * Specifies a class implementing {@link jakarta.persistence.spi.PersistenceProvider}. - * Naturally, this should always be {@link org.hibernate.jpa.HibernatePersistenceProvider}, - * which is the best damn persistence provider ever. There's no need to explicitly specify - * this setting when there are no inferior persistence providers floating about. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.4 - */ - String JAKARTA_PERSISTENCE_PROVIDER = "jakarta.persistence.provider"; - - /** - * Specifies the {@linkplain jakarta.persistence.spi.PersistenceUnitTransactionType - * type of transactions} supported by the entity managers. The default depends on - * whether the program is considered to be executing in a Java SE or EE environment: - *

    - *
  • For Java SE, the default is - * {@link jakarta.persistence.spi.PersistenceUnitTransactionType#RESOURCE_LOCAL - * RESOURCE_LOCAL}. - *
  • For Java EE, the default is - * {@link jakarta.persistence.spi.PersistenceUnitTransactionType#JTA JTA}. - *
- *

- * See JPA 2 sections 9.4.3 and 8.2.1.2 - */ - String JAKARTA_TRANSACTION_TYPE = "jakarta.persistence.transactionType"; - - /** - * Specifies the JNDI name of a JTA {@link javax.sql.DataSource}. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.5 - */ - String JAKARTA_JTA_DATASOURCE = "jakarta.persistence.jtaDataSource"; - - /** - * Specifies the JNDI name of a non-JTA {@link javax.sql.DataSource}. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.5 - */ - String JAKARTA_NON_JTA_DATASOURCE = "jakarta.persistence.nonJtaDataSource"; - - /** - * Specifies the name of a JDBC driver to use to connect to the database. - *

- * Used in conjunction with {@link #JPA_JDBC_URL}, {@link #JPA_JDBC_USER} - * and {@link #JPA_JDBC_PASSWORD} to specify how to connect to the database. - *

- * When connections are obtained from a {@link javax.sql.DataSource}, use - * either {@link #JPA_JTA_DATASOURCE} or {@link #JPA_NON_JTA_DATASOURCE} - * instead. - *

- * See section 8.2.1.9 - */ - String JAKARTA_JDBC_DRIVER = "jakarta.persistence.jdbc.driver"; - - /** - * Specifies the JDBC connection URL to use to connect to the database. - *

- * Used in conjunction with {@link #JPA_JDBC_DRIVER}, {@link #JPA_JDBC_USER} - * and {@link #JPA_JDBC_PASSWORD} to specify how to connect to the database. - *

- * When connections are obtained from a {@link javax.sql.DataSource}, use - * either {@link #JPA_JTA_DATASOURCE} or {@link #JPA_NON_JTA_DATASOURCE} - * instead. - *

- * See section 8.2.1.9 - */ - String JAKARTA_JDBC_URL = "jakarta.persistence.jdbc.url"; - - /** - * Specifies the database user to use when connecting via JDBC. - *

- * Used in conjunction with {@link #JPA_JDBC_DRIVER}, {@link #JPA_JDBC_URL} - * and {@link #JPA_JDBC_PASSWORD} to specify how to connect to the database. - *

- * See section 8.2.1.9 - */ - String JAKARTA_JDBC_USER = "jakarta.persistence.jdbc.user"; - - /** - * Specifies the password to use when connecting via JDBC. - *

- * Used in conjunction with {@link #JPA_JDBC_DRIVER}, {@link #JPA_JDBC_URL} - * and {@link #JPA_JDBC_USER} to specify how to connect to the database. - *

- * See JPA 2 section 8.2.1.9 - */ - String JAKARTA_JDBC_PASSWORD = "jakarta.persistence.jdbc.password"; - - /** - * When enabled, specifies that the second-level cache (which JPA calls the - * "shared" cache) may be used, as per the rules defined in JPA 2 section 3.1.7. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.7 - * - * @see jakarta.persistence.SharedCacheMode - */ - String JAKARTA_SHARED_CACHE_MODE = "jakarta.persistence.sharedCache.mode"; - - /** - * Set a default value for {@link SpecHints#HINT_SPEC_CACHE_RETRIEVE_MODE}, - * used when the hint is not explicitly specified. - *

- * It does not usually make sense to change the default from - * {@link jakarta.persistence.CacheRetrieveMode#USE}. - * - * @see SpecHints#HINT_SPEC_CACHE_RETRIEVE_MODE - */ - String JAKARTA_SHARED_CACHE_RETRIEVE_MODE = SpecHints.HINT_SPEC_CACHE_RETRIEVE_MODE; - - /** - * Set a default value for {@link SpecHints#HINT_SPEC_CACHE_STORE_MODE}, - * used when the hint is not explicitly specified. - *

- * It does not usually make sense to change the default from - * {@link jakarta.persistence.CacheStoreMode#USE}. - * - * @see SpecHints#HINT_SPEC_CACHE_RETRIEVE_MODE - */ - String JAKARTA_SHARED_CACHE_STORE_MODE = SpecHints.HINT_SPEC_CACHE_STORE_MODE; - - /** - * Indicates which {@linkplain jakarta.persistence.ValidationMode form of automatic - * validation} is in effect as per the rules defined in JPA 2 section 3.6.1.1. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.8 - * - * @see jakarta.persistence.ValidationMode - */ - String JAKARTA_VALIDATION_MODE = "jakarta.persistence.validation.mode"; - - /** - * Used to pass along any discovered {@link jakarta.validation.ValidatorFactory}. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyValidatorFactory(Object) - */ - String JAKARTA_VALIDATION_FACTORY = "jakarta.persistence.validation.factory"; - - /** - * Used to coordinate with bean validators. - *

- * See JPA 2 section 8.2.1.9 - */ - @SuppressWarnings("unused") - String JAKARTA_PERSIST_VALIDATION_GROUP = "jakarta.persistence.validation.group.pre-persist"; - - /** - * Used to coordinate with bean validators. - *

- * See JPA 2 section 8.2.1.9 - */ - @SuppressWarnings("unused") - String JAKARTA_UPDATE_VALIDATION_GROUP = "jakarta.persistence.validation.group.pre-update"; - - /** - * Used to coordinate with bean validators. - *

- * See JPA 2 section 8.2.1.9 - */ - @SuppressWarnings("unused") - String JAKARTA_REMOVE_VALIDATION_GROUP = "jakarta.persistence.validation.group.pre-remove"; + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * Set a default value for the hint {@link SpecHints#HINT_SPEC_LOCK_SCOPE}, @@ -244,931 +60,28 @@ public interface AvailableSettings { String JAKARTA_LOCK_TIMEOUT = SpecHints.HINT_SPEC_LOCK_TIMEOUT; /** - * Used to pass a CDI {@link jakarta.enterprise.inject.spi.BeanManager} to - * Hibernate. - *

- * According to the JPA specification, the {@code BeanManager} should be - * passed at boot time and be ready for immediate use at that time. But - * not all environments can do this (WildFly, for example). To accommodate - * such environments, Hibernate provides two options:

    - *
  1. A proprietary CDI extension SPI (which has been proposed to the CDI - * spec group as a standard option) which can be used to provide delayed - * {@code BeanManager} access: to use this solution, the reference passed - * as the {@code BeanManager} during bootstrap should be typed as - * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager}. - *
  2. Delayed access to the {@code BeanManager} reference: here, Hibernate - * will not access the reference passed as the {@code BeanManager} during - * bootstrap until it is first needed. Note, however, that this has the - * effect of delaying the detection of any deployment problems until after - * bootstrapping. - *
- * - * This setting is used to configure access to the {@code BeanManager}, - * either directly, or via - * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager}. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyBeanManager(Object) - */ - String JAKARTA_CDI_BEAN_MANAGER = "jakarta.persistence.bean.manager"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // BootstrapServiceRegistry level settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * Specifies a {@link java.util.Collection collection} of the {@link ClassLoader} - * instances Hibernate should use for classloading and resource loading. - * - * @since 5.0 - */ - String CLASSLOADERS = "hibernate.classLoaders"; - - /** - * Specifies how the {@linkplain Thread#getContextClassLoader() thread context} - * {@linkplain ClassLoader class loader} must be used for class lookup. - * - * @see org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence - */ - String TC_CLASSLOADER = "hibernate.classLoader.tccl_lookup_precedence"; - - /** - * Setting that indicates whether to build the JPA types, either:
    - *
  • - * enabled - Do the build - *
  • - *
  • - * disabled - Do not do the build - *
  • - *
  • - * ignoreUnsupported - Do the build, but ignore any non-JPA - * features that would otherwise result in a failure. - *
  • - *
- */ - String JPA_METAMODEL_POPULATION = "hibernate.jpa.metamodel.population"; - - /** - * Setting that controls whether we seek out JPA "static metamodel" classes - * and populate them, either:
    - *
  • - * enabled - Do the population - *
  • - *
  • - * disabled - Do not do the population - *
  • - *
  • - * skipUnsupported - Do the population, but ignore any non-JPA - * features that would otherwise result in the population failing. - *
  • - *
- */ - String STATIC_METAMODEL_POPULATION = "hibernate.jpa.static_metamodel.population"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // StandardServiceRegistry level settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * Specifies a {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} - * to use for obtaining JDBC connections, either: - *
    - *
  • an instance of {@code ConnectionProvider}, - *
  • a {@link Class} representing a class that implements - * {@code ConnectionProvider}, or - *
  • the name of a class that implements {@code ConnectionProvider}. - *
- *

- * The term {@code "class"} appears in the setting name due to legacy reasons; - * however it can accept instances. - */ - String CONNECTION_PROVIDER = "hibernate.connection.provider_class"; - - /** - * Specifies the {@linkplain java.sql.Driver JDBC driver} class. - * - * @see java.sql.Driver - * @see #JAKARTA_JDBC_DRIVER - */ - String DRIVER = "hibernate.connection.driver_class"; - - /** - * Specifies the JDBC connection URL. - * - * @see #JAKARTA_JDBC_URL - */ - String URL = "hibernate.connection.url"; - - /** - * Specifies the database user to use when connecting via JDBC. - *

- * Depending on the configured - * {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider}, the - * specified username might be used to: - *

    - *
  • create a JDBC connection using - * {@link java.sql.DriverManager#getConnection(String,java.util.Properties)} - * or {@link java.sql.Driver#connect(String,java.util.Properties)}, or - *
  • obtain a JDBC connection from a datasource, using - * {@link javax.sql.DataSource#getConnection(String, String)}. - *
- * - * @see #PASS - * @see #JAKARTA_JDBC_PASSWORD - */ - String USER = "hibernate.connection.username"; - - /** - * Specifies password to use when connecting via JDBC. - * - * @see #USER - * @see #JAKARTA_JDBC_USER - */ - String PASS = "hibernate.connection.password"; - - /** - * Specified the JDBC transaction isolation level. - */ - String ISOLATION = "hibernate.connection.isolation"; - - /** - * Controls the autocommit mode of JDBC connections obtained from any - * {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} implementation - * which respects this setting, which the built-in implementations do, except for - * {@link org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl}. - */ - String AUTOCOMMIT = "hibernate.connection.autocommit"; - - /** - * Specifies the maximum number of inactive connections for the built-in - * {@linkplain org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl - * connection pool}. - */ - String POOL_SIZE = "hibernate.connection.pool_size"; - - /** - * Specifies a {@link javax.sql.DataSource}, either: - *
    - *
  • an instance of {@link javax.sql.DataSource}, or - *
  • a JNDI name under which to obtain the {@link javax.sql.DataSource}. - *
- *

- * For JNDI names, see also {@link #JNDI_CLASS}, {@link #JNDI_URL}, {@link #JNDI_PREFIX}, etc. - * - * @see javax.sql.DataSource - * @see #JAKARTA_JTA_DATASOURCE - * @see #JAKARTA_NON_JTA_DATASOURCE - */ - String DATASOURCE = "hibernate.connection.datasource"; - - /** - * Allows a user to tell Hibernate that the connections we obtain from the configured - * {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} will already - * have autocommit disabled when we acquire them from the provider. When we obtain - * connections with autocommit already disabled, we may circumvent some operations in - * the interest of performance. - *

- * By default, Hibernate calls {@link java.sql.Connection#setAutoCommit(boolean)} on - * newly-obtained connections. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyConnectionProviderDisablesAutoCommit(boolean) - * - * @since 5.2.10 - */ - String CONNECTION_PROVIDER_DISABLES_AUTOCOMMIT= "hibernate.connection.provider_disables_autocommit"; - - /** - * A prefix for properties specifying arbitrary JDBC connection properties. These - * properties are simply passed along to the provider when creating a connection. - */ - String CONNECTION_PREFIX = "hibernate.connection"; - - /** - * Specifies the JNDI {@link javax.naming.InitialContext} implementation class. - * - * @see javax.naming.Context#INITIAL_CONTEXT_FACTORY - */ - String JNDI_CLASS = "hibernate.jndi.class"; - - /** - * Specifies the JNDI provider/connection URL. - * - * @see javax.naming.Context#PROVIDER_URL - */ - String JNDI_URL = "hibernate.jndi.url"; - - /** - * A prefix for properties specifying arbitrary JNDI {@link javax.naming.InitialContext} - * properties. These properties are simply passed along to the constructor - * {@link javax.naming.InitialContext#InitialContext(java.util.Hashtable)}. - */ - String JNDI_PREFIX = "hibernate.jndi"; - - /** - * Specifies the Hibernate {@linkplain org.hibernate.dialect.Dialect SQL dialect}, either - *

    - *
  • an instance of {@link org.hibernate.dialect.Dialect}, - *
  • a {@link Class} representing a class that extends {@code Dialect}, or - *
  • the name of a class that extends {@code Dialect}. - *
- *

- * By default, Hibernate will attempt to automatically determine the dialect from the - * {@linkplain #URL JDBC URL} and JDBC metadata, so this setting is not usually necessary. - * - * @apiNote As of Hibernate 6, this property should not be explicitly specified, - * except when using a custom user-written implementation of {@code Dialect}. - * Instead, applications should allow Hibernate to select the {@code Dialect} - * automatically. - * - * @see org.hibernate.dialect.Dialect - */ - String DIALECT = "hibernate.dialect"; - - /** - * Specifies additional {@link org.hibernate.engine.jdbc.dialect.spi.DialectResolver} - * implementations to register with the standard - * {@link org.hibernate.engine.jdbc.dialect.spi.DialectFactory}. - */ - String DIALECT_RESOLVERS = "hibernate.dialect_resolvers"; - - /** - * Specifies the name of the database provider in cases where a connection to the - * database is not available (usually for generating scripts). In such cases, a value - * for this setting must be specified. - *

- * The value of this setting is expected to match the value returned by - * {@link java.sql.DatabaseMetaData#getDatabaseProductName()} for the target database. - *

- * Additionally, specifying {@value #DIALECT_DB_MAJOR_VERSION}, and perhaps even - * {@value #DIALECT_DB_MINOR_VERSION}, may be required for high quality DDL generation. - * - * @see #DIALECT_DB_VERSION - * @see #DIALECT_DB_MAJOR_VERSION - * @see #DIALECT_DB_MINOR_VERSION - * - * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_NAME} instead + * @deprecated Use {@link #JAKARTA_LOCK_SCOPE} instead */ @Deprecated @SuppressWarnings("DeprecatedIsStillUsed") - String DIALECT_DB_NAME = "javax.persistence.database-product-name"; + String JPA_LOCK_SCOPE = LegacySpecHints.HINT_JAVAEE_LOCK_SCOPE; /** - * Specifies the name of the database provider in cases where a connection to the - * database is not available (usually for generating scripts). This value is used - * to help more precisely determine how to perform schema generation tasks for the - * underlying database in cases where {@value #DIALECT_DB_NAME} does not provide - * enough distinction. - *

- * The value of this setting is expected to match the value returned by - * {@link java.sql.DatabaseMetaData#getDatabaseProductVersion()} for the target - * database. - * - * @see #DIALECT_DB_NAME - * - * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_VERSION} instead + * @deprecated Use {@link #JAKARTA_LOCK_TIMEOUT} instead */ @Deprecated @SuppressWarnings("DeprecatedIsStillUsed") - String DIALECT_DB_VERSION = "javax.persistence.database-product-version"; - - /** - * Specifies the major version of the underlying database, as would be returned by - * {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion} for the target database. - * This value is used to help more precisely determine how to perform schema generation - * tasks for the database in cases where {@value #DIALECT_DB_NAME} does not provide - * enough distinction. - * - * @see #DIALECT_DB_NAME - * @see #DIALECT_DB_MINOR_VERSION - * - * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_MAJOR_VERSION} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String DIALECT_DB_MAJOR_VERSION = "javax.persistence.database-major-version"; - - /** - * Specifies the minor version of the underlying database, as would be returned by - * {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion} for the target database. - * This setting is used in {@link org.hibernate.dialect.Dialect} resolution. - * - * @see #DIALECT_DB_NAME - * @see #DIALECT_DB_MAJOR_VERSION - * @see org.hibernate.engine.jdbc.dialect.spi.DialectResolver - * - * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_MINOR_VERSION} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String DIALECT_DB_MINOR_VERSION = "javax.persistence.database-minor-version"; - - /** - * Specifies the default storage engine for a relational databases that supports - * multiple storage engines. This property must be set either as an {@link Environment} - * variable or JVM System Property, since the {@link org.hibernate.dialect.Dialect} is - * instantiated before Hibernate property resolution. - * - * @since 5.2.9 - */ - String STORAGE_ENGINE = "hibernate.dialect.storage_engine"; - - /** - * Specifies the {@link org.hibernate.tool.schema.spi.SchemaManagementTool} to use for - * performing schema management. - *

- * By default, {@link org.hibernate.tool.schema.internal.HibernateSchemaManagementTool} - * is used. - * - * @since 5.0 - */ - String SCHEMA_MANAGEMENT_TOOL = "hibernate.schema_management_tool"; - - /** - * Specify the {@link org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder} - * implementation to use for creating instances of - * {@link org.hibernate.resource.transaction.spi.TransactionCoordinator}, either: - *

    - *
  • an instance of {@code TransactionCoordinatorBuilder}, - *
  • a {@link Class} representing a class that implements {@code TransactionCoordinatorBuilder}, or - *
  • the name of a class that implements {@code TransactionCoordinatorBuilder}. - *
- * - * @since 5.0 - */ - String TRANSACTION_COORDINATOR_STRATEGY = "hibernate.transaction.coordinator_class"; - - /** - * Specifies the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform} - * implementation to use for integrating with JTA, either: - *
    - *
  • an instance of {@code JtaPlatform}, or - *
  • the name of a class that implements {@code JtaPlatform}. - *
- * - * @see #JTA_PLATFORM_RESOLVER - * - * @since 4.0 - */ - String JTA_PLATFORM = "hibernate.transaction.jta.platform"; - - /** - * When enabled, specifies that the {@link jakarta.transaction.UserTransaction} should - * be used in preference to the {@link jakarta.transaction.TransactionManager} for JTA - * transaction management. - *

- * By default, the {@code TransactionManager} is preferred. - * - * @see org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform#retrieveUserTransaction - * @see org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform#retrieveTransactionManager - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyPreferUserTransactions(boolean) - * - * @since 5.0 - */ - String PREFER_USER_TRANSACTION = "hibernate.jta.prefer_user_transaction"; - - /** - * Specifies a {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformResolver} - * implementation that should be used to obtain an instance of - * {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform}. - * - * @see #JTA_PLATFORM - * - * @since 4.3 - */ - String JTA_PLATFORM_RESOLVER = "hibernate.transaction.jta.platform_resolver"; - - /** - * When enabled, indicates that it is safe to cache {@link jakarta.transaction.TransactionManager} - * references. - * - * @since 4.0 - */ - String JTA_CACHE_TM = "hibernate.jta.cacheTransactionManager"; - - /** - * When enabled, indicates that it is safe to cache {@link jakarta.transaction.UserTransaction} - * references. - * - * @since 4.0 - */ - String JTA_CACHE_UT = "hibernate.jta.cacheUserTransaction"; + String JPA_LOCK_TIMEOUT = LegacySpecHints.HINT_JAVAEE_LOCK_TIMEOUT; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // MetadataBuilder level settings + // Hibernate settings // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * A default database catalog name to use for unqualified table names - * - * @see org.hibernate.boot.MetadataBuilder#applyImplicitCatalogName - */ - String DEFAULT_CATALOG = "hibernate.default_catalog"; - - /** - * A default database schema (owner) name to use for unqualified table names - * - * @see org.hibernate.boot.MetadataBuilder#applyImplicitSchemaName - */ - String DEFAULT_SCHEMA = "hibernate.default_schema"; - - /** - * Specifies the {@link org.hibernate.annotations.CacheConcurrencyStrategy} to use by - * default when an entity is marked {@link jakarta.persistence.Cacheable @Cacheable}, - * but no concurrency strategy is explicitly specified via the - * {@link org.hibernate.annotations.Cache} annotation. - *

- * An explicit strategy may be specified using - * {@link org.hibernate.annotations.Cache#usage @Cache(usage=...)}. - * - * @see org.hibernate.boot.MetadataBuilder#applyAccessType(org.hibernate.cache.spi.access.AccessType) - */ - String DEFAULT_CACHE_CONCURRENCY_STRATEGY = "hibernate.cache.default_cache_concurrency_strategy"; - - /** - * @see org.hibernate.boot.MetadataBuilder#enableImplicitForcingOfDiscriminatorsInSelect - */ - String FORCE_DISCRIMINATOR_IN_SELECTS_BY_DEFAULT = "hibernate.discriminator.force_in_select"; - - /** - * The legacy behavior of Hibernate is to not use discriminators for joined inheritance - * (Hibernate does not need the discriminator.). However, some JPA providers do need the - * discriminator for handling joined inheritance, so in the interest of portability this - * capability has been added to Hibernate. - *

- * However, we want to make sure that legacy applications continue to work as well. - * Which puts us in a bind in terms of how to handle "implicit" discriminator mappings. - * The solution is to assume that the absence of discriminator metadata means to follow - * the legacy behavior unless this setting is enabled. With this setting enabled, - * Hibernate will interpret the absence of discriminator metadata as an indication to use - * the JPA defined defaults for these absent annotations. - *

- * See Hibernate Jira issue HHH-6911 for additional background info. - *

- * This setting defaults to {@code false}, meaning that implicit discriminator columns - * are never inferred to exist for joined inheritance hierarchies. - * - * @see org.hibernate.boot.MetadataBuilder#enableImplicitDiscriminatorsForJoinedSubclassSupport - * @see #IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS - */ - String IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS = "hibernate.discriminator.implicit_for_joined"; - - /** - * The legacy behavior of Hibernate is to not use discriminators for joined inheritance - * (Hibernate does not need the discriminator). However, some JPA providers do need the - * discriminator for handling joined inheritance, so in the interest of portability this - * capability has been added to Hibernate. - *

- * Existing applications rely (implicitly or explicitly) on Hibernate ignoring any - * {@link jakarta.persistence.DiscriminatorColumn} declarations on joined inheritance - * hierarchies. This setting allows these applications to maintain the legacy behavior - * of {@code @DiscriminatorColumn} annotations being ignored when paired with joined - * inheritance. - *

- * See Hibernate Jira issue HHH-6911 for additional background info. - *

- * This setting defaults to {@code false}, meaning that explicit discriminator columns - * are never ignored. - * - * @see org.hibernate.boot.MetadataBuilder#enableExplicitDiscriminatorsForJoinedSubclassSupport - * @see #IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS - */ - String IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS = "hibernate.discriminator.ignore_explicit_for_joined"; - - /** - * By default, Hibernate maps character data represented by {@link String}s and - * {@link java.sql.Clob}s to the JDBC types {@link java.sql.Types#VARCHAR} and - * {@link java.sql.Types#CLOB}. This setting, when enabled, turns on the use of - * explicit nationalized character support for mappings involving character - * data, specifying that the JDBC types {@link java.sql.Types#NVARCHAR} and - * {@link java.sql.Types#NCLOB} should be used instead. - *

- * This setting is relevant for use with databases with - * {@linkplain org.hibernate.dialect.NationalizationSupport#EXPLICIT explicit - * nationalization support}, and it is not needed for databases whose native - * {@code varchar} and {@code clob} types support Unicode data. (If you're not - * sure how your database handles Unicode, check out the implementation of - * {@link org.hibernate.dialect.Dialect#getNationalizationSupport()} for its - * SQL dialect.) - *

- * Enabling this setting has two effects: - *

    - *
  1. when interacting with JDBC, Hibernate uses operations like - * {@link java.sql.PreparedStatement#setNString(int, String)} - * {@link java.sql.PreparedStatement#setNClob(int, java.sql.NClob)} - * to pass character data, and - *
  2. when generating DDL, the schema export tool uses {@code nchar}, - * {@code nvarchar}, or {@code nclob} as the generated column - * type when no column type is explicitly specified using - * {@link jakarta.persistence.Column#columnDefinition()}. - *
- *

- * This setting is disabled by default, and so Unicode character data - * may not be persisted correctly for databases with explicit nationalization - * support. - *

- * This is a global setting applying to all mappings associated with a given - * {@link org.hibernate.SessionFactory}. - * The {@link org.hibernate.annotations.Nationalized} annotation may be used - * to selectively enable nationalized character support for specific columns. - * - * @see org.hibernate.boot.MetadataBuilder#enableGlobalNationalizedCharacterDataSupport(boolean) - * @see org.hibernate.dialect.NationalizationSupport - * @see org.hibernate.annotations.Nationalized - */ - String USE_NATIONALIZED_CHARACTER_DATA = "hibernate.use_nationalized_character_data"; - - /** - * Specifies an implementation of {@link org.hibernate.boot.archive.scan.spi.Scanner}, - * either: - *

    - *
  • an instance of {@code Scanner}, - *
  • a {@link Class} representing a class that implements {@code Scanner} - *
  • the name of a class that implements {@code Scanner}. - *
- * - * @see org.hibernate.boot.MetadataBuilder#applyScanner - */ - String SCANNER = "hibernate.archive.scanner"; - - /** - * Specifies an {@link org.hibernate.boot.archive.spi.ArchiveDescriptorFactory} to use - * in the scanning process, either: - *
    - *
  • an instance of {@code ArchiveDescriptorFactory}, - *
  • a {@link Class} representing a class that implements {@code ArchiveDescriptorFactory}, or - *
  • the name of a class that implements {@code ArchiveDescriptorFactory}. - *
- *

- * See information on {@link org.hibernate.boot.archive.scan.spi.Scanner} - * about expected constructor forms. - * - * @see #SCANNER - * @see org.hibernate.boot.archive.scan.spi.Scanner - * @see org.hibernate.boot.archive.scan.spi.AbstractScannerImpl - * @see org.hibernate.boot.MetadataBuilder#applyArchiveDescriptorFactory - */ - String SCANNER_ARCHIVE_INTERPRETER = "hibernate.archive.interpreter"; - - /** - * Identifies a comma-separated list of values indicating the types of things we should - * auto-detect during scanning. Allowable values include: - *

    - *
  • {@code "class"} specifies that {@code .class} files are discovered as managed classes - *
  • {@code "hbm"} specifies that {@code hbm.xml} files are discovered as mapping files - *
- * - * @see org.hibernate.boot.MetadataBuilder#applyScanOptions - */ - String SCANNER_DISCOVERY = "hibernate.archive.autodetection"; - - /** - * Used to specify the {@link org.hibernate.boot.model.naming.ImplicitNamingStrategy} - * class to use. The following shortcut names are defined for this setting: - *
    - *
  • {@code "default"} and {@code "jpa"} are an abbreviations for - * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl} - *
  • {@code "legacy-jpa"} is an abbreviation for - * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl} - *
  • {@code "legacy-hbm"} is an abbreviation for - * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl} - *
  • {@code "component-path"} is an abbreviation for - * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl} - *
- *

- * By default, the {@code ImplicitNamingStrategy} registered under the key - * {@code "default"} is used. If no strategy is explicitly registered under that key, - * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl} is used. - * - * @see org.hibernate.boot.MetadataBuilder#applyImplicitNamingStrategy - * - * @since 5.0 - */ - String IMPLICIT_NAMING_STRATEGY = "hibernate.implicit_naming_strategy"; - - /** - * Specifies the {@link org.hibernate.boot.model.naming.PhysicalNamingStrategy} to use. - *

- * By default, {@link org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl} - * is used, in which case physical names are taken to be identical to logical names. - * - * @see org.hibernate.boot.MetadataBuilder#applyPhysicalNamingStrategy - * - * @since 5.0 - */ - String PHYSICAL_NAMING_STRATEGY = "hibernate.physical_naming_strategy"; - - /** - * An implicit naming strategy for database structures (tables, sequences) related - * to identifier generators. - *

- * Resolution uses the {@link org.hibernate.boot.registry.selector.spi.StrategySelector} - * service and accepts any of the forms discussed on - * {@link StrategySelector#resolveDefaultableStrategy(Class, Object, java.util.concurrent.Callable)}. - *

- * The recognized short names being:

    - *
  • {@value org.hibernate.id.enhanced.SingleNamingStrategy#STRATEGY_NAME}
  • - *
  • {@value org.hibernate.id.enhanced.LegacyNamingStrategy#STRATEGY_NAME}
  • - *
  • {@value org.hibernate.id.enhanced.StandardNamingStrategy#STRATEGY_NAME}
  • - *
- *

- * By default, {@link org.hibernate.id.enhanced.StandardNamingStrategy} is used. - * - * @since 6 - * - * @see ImplicitDatabaseObjectNamingStrategy - */ - @Incubating - String ID_DB_STRUCTURE_NAMING_STRATEGY = "hibernate.id.db_structure_naming_strategy"; - - /** - * Used to specify the {@link org.hibernate.boot.model.relational.ColumnOrderingStrategy} - * class to use. The following shortcut names are defined for this setting: - *

    - *
  • {@code "default"} is an abbreviations for - * {@link org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard} - *
  • {@code "legacy"} is an abbreviation for - * {@link org.hibernate.boot.model.relational.ColumnOrderingStrategyLegacy} - *
- *

- * By default, the {@linkplain org.hibernate.boot.model.relational.ColumnOrderingStrategy} registered under the key - * {@code "default"} is used. If no strategy is explicitly registered under that key, - * {@link org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard} is used. - * - * @see org.hibernate.boot.MetadataBuilder#applyColumnOrderingStrategy - * - * @since 6.2 - */ - String COLUMN_ORDERING_STRATEGY = "hibernate.column_ordering_strategy"; - - /** - * Specifies the order in which metadata sources should be processed, is a delimited list - * of values defined by {@link MetadataSourceType}. - *

- * The default is {@code "hbm,class"} which that {@code hbm.xml} files should be processed - * first, followed by annotations (combined with {@code orm.xml} mappings). - * - * @see MetadataSourceType - * @see org.hibernate.boot.MetadataBuilder#applySourceProcessOrdering(MetadataSourceType...) - * - * @deprecated {@code hbm.xml} mappings are no longer supported, making this attribute irrelevant - */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated(since = "6", forRemoval = true) - String ARTIFACT_PROCESSING_ORDER = "hibernate.mapping.precedence"; - - /** - * Specifies whether to automatically quote any names that are deemed SQL keywords. - *

- * Auto-quoting of SQL keywords is disabled by default. - * - * @since 5.0 - */ - String KEYWORD_AUTO_QUOTING_ENABLED = "hibernate.auto_quote_keyword"; - - /** - * When disabled, specifies that processing of XML-based mappings should be skipped. - *

- * This is a performance optimization appropriate when all O/R mappings are defined - * exclusively using annotations. - *

- * By default, the XML-based mappings are taken into account. - * - * @since 5.4.1 - */ - String XML_MAPPING_ENABLED = "hibernate.xml_mapping_enabled"; - - /** - * Specifies the {@link org.hibernate.metamodel.CollectionClassification} to use when - * Hibernate detects a plural attribute typed as {@link java.util.List} with no explicit - * list index configuration. - *

- * Accepts any of: - *

    - *
  • an instance of {@code CollectionClassification} - *
  • the (case insensitive) name of a {@code CollectionClassification} (list e.g.) - *
  • a {@link Class} representing either {@link java.util.List} or {@link java.util.Collection} - *
- *

- * By default, when this property is not set, an attribute of type {@code List} - * is taken to have the semantics of a - * {@linkplain org.hibernate.metamodel.CollectionClassification#BAG bag} unless - * it is annotated {@link jakarta.persistence.OrderColumn} or - * {@link org.hibernate.annotations.ListIndexBase}. - * - * @since 6.0 - * - * @see org.hibernate.annotations.Bag - */ - String DEFAULT_LIST_SEMANTICS = "hibernate.mapping.default_list_semantics"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // SessionFactoryBuilder level settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * Setting used to name the Hibernate {@link org.hibernate.SessionFactory}. - *

- * Naming the SessionFactory allows for it to be properly serialized across JVMs as - * long as the same name is used on each JVM. - *

- * If {@link #SESSION_FACTORY_NAME_IS_JNDI} is set to {@code true}, this is also the - * name under which the SessionFactory is bound into JNDI on startup and from which - * it can be obtained from JNDI. - * - * @see #SESSION_FACTORY_NAME_IS_JNDI - * @see org.hibernate.internal.SessionFactoryRegistry - * @see org.hibernate.boot.SessionFactoryBuilder#applyName(String) - */ - String SESSION_FACTORY_NAME = "hibernate.session_factory_name"; - - /** - * Does the value defined by {@link #SESSION_FACTORY_NAME} represent a JNDI namespace - * into which the {@link org.hibernate.SessionFactory} should be bound and made accessible? - *

- * Defaults to {@code true} for backwards compatibility. - *

- * Set this to {@code false} if naming a SessionFactory is needed for serialization purposes, - * but no writable JNDI context exists in the runtime environment or if the user simply does - * not want JNDI to be used. - * - * @see #SESSION_FACTORY_NAME - * @see org.hibernate.boot.SessionFactoryBuilder#applyNameAsJndiName(boolean) - */ - String SESSION_FACTORY_NAME_IS_JNDI = "hibernate.session_factory_name_is_jndi"; - - /** - * Enables logging of generated SQL to the console. - */ - String SHOW_SQL = "hibernate.show_sql"; - - /** - * Enables formatting of SQL logged to the console. - */ - String FORMAT_SQL = "hibernate.format_sql"; - - /** - * Enables highlighting of SQL logged to the console using ANSI escape codes. - */ - String HIGHLIGHT_SQL = "hibernate.highlight_sql"; - - /** - * Specifies that comments should be added to the generated SQL. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applySqlComments(boolean) - */ - String USE_SQL_COMMENTS = "hibernate.use_sql_comments"; - - /** - * Specifies the maximum depth of nested outer join fetching. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyMaximumFetchDepth(int) - */ - String MAX_FETCH_DEPTH = "hibernate.max_fetch_depth"; - - /** - * Specifies the default batch size for batch fetching. When set to - * a value greater than one, Hibernate will use batch fetching, when - * possible, to fetch any association. - *

- * By default, Hibernate only uses batch fetching for entities and - * collections explicitly annotated {@code @BatchSize}. - * - * @see org.hibernate.annotations.BatchSize - * @see org.hibernate.Session#setFetchBatchSize(int) - * @see org.hibernate.boot.SessionFactoryBuilder#applyDefaultBatchFetchSize(int) - */ - String DEFAULT_BATCH_FETCH_SIZE = "hibernate.default_batch_fetch_size"; - - /** - * When enabled, Hibernate will use subselect fetching, when possible, to - * fetch any collection. - *

- * By default, Hibernate only uses subselect fetching for collections - * explicitly annotated {@code @Fetch(SUBSELECT)}. - * - * @since 6.3 - * - * @see org.hibernate.annotations.FetchMode#SUBSELECT - * @see org.hibernate.Session#setSubselectFetchingEnabled(boolean) - * @see org.hibernate.boot.SessionFactoryBuilder#applySubselectFetchEnabled(boolean) - */ - String USE_SUBSELECT_FETCH = "hibernate.use_subselect_fetch"; - - /** - * When enabled, specifies that JDBC scrollable {@code ResultSet}s may be used. - * This property is only necessary when there is no {@code ConnectionProvider}, - * that is, when the client is supplying JDBC connections. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyScrollableResultsSupport(boolean) - */ - String USE_SCROLLABLE_RESULTSET = "hibernate.jdbc.use_scrollable_resultset"; - - /** - * Specifies that generated primary keys may be retrieved using the JDBC 3 - * {@link java.sql.PreparedStatement#getGeneratedKeys()} operation. - *

- * Usually, performance will be improved if this behavior is enabled, assuming - * the JDBC driver supports {@code getGeneratedKeys()}. - * - * @see java.sql.PreparedStatement#getGeneratedKeys - * @see org.hibernate.boot.SessionFactoryBuilder#applyGetGeneratedKeysSupport(boolean) - */ - String USE_GET_GENERATED_KEYS = "hibernate.jdbc.use_get_generated_keys"; - - /** - * Gives the JDBC driver a hint as to the number of rows that should be fetched - * from the database when more rows are needed. If {@code 0}, the JDBC driver's - * default settings will be used. - * - * @see java.sql.PreparedStatement#setFetchSize(int) - * @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcFetchSize(int) - * @see org.hibernate.ScrollableResults#setFetchSize(int) - */ - String STATEMENT_FETCH_SIZE = "hibernate.jdbc.fetch_size"; - - /** - * Specifies the maximum JDBC batch size. A nonzero value enables batch updates. - * - * @see java.sql.PreparedStatement#executeBatch() - * @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchSize(int) - */ - String STATEMENT_BATCH_SIZE = "hibernate.jdbc.batch_size"; - - /** - * Specifies a custom {@link BatchBuilder}. - */ - String BATCH_STRATEGY = "hibernate.jdbc.factory_class"; - - /** - * When enabled, specifies that {@linkplain jakarta.persistence.Version versioned} - * data should be included in batching. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchingForVersionedEntities(boolean) - */ - String BATCH_VERSIONED_DATA = "hibernate.jdbc.batch_versioned_data"; - - /** - * Specifies the {@linkplain java.util.TimeZone time zone} to use in the JDBC driver, - * which is supposed to match the database timezone. - *

- * This is the timezone what will be passed to - * {@link java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)} - * {@link java.sql.PreparedStatement#setTime(int, java.sql.Time, java.util.Calendar)}, - * {@link java.sql.ResultSet#getTimestamp(int, Calendar)}, and - * {@link java.sql.ResultSet#getTime(int, Calendar)} when binding parameters. - *

- * The time zone may be given as: - *

    - *
  • an instance of {@link java.util.TimeZone}, - *
  • an instance of {@link java.time.ZoneId}, or - *
  • a time zone ID string to be passed to {@link java.time.ZoneId#of(String)}. - *
- *

- * By default, the {@linkplain java.util.TimeZone#getDefault() JVM default time zone} - * is assumed by the JDBC driver. - * - * @since 5.2.3 - */ - String JDBC_TIME_ZONE = "hibernate.jdbc.time_zone"; - - /** - * When enabled, specifies that the {@link org.hibernate.Session} should be - * closed automatically at the end of each transaction. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyAutoClosing(boolean) - */ - String AUTO_CLOSE_SESSION = "hibernate.transaction.auto_close_session"; - - /** - * When enabled, specifies that automatic flushing should occur during the JTA - * {@link jakarta.transaction.Synchronization#beforeCompletion()} callback. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyAutoFlushing(boolean) - */ - String FLUSH_BEFORE_COMPLETION = "hibernate.transaction.flush_before_completion"; - - /** - * Specifies how Hibernate should manage JDBC connections in terms of acquisition - * and release, either: - *

    - *
  • an instance of the enumeration - * {@link org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode}, - * or - *
  • the name of one of its instances. - *
- *

- * The default is {@code DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION}. - * - * @see org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode - * @see org.hibernate.boot.SessionFactoryBuilder#applyConnectionHandlingMode(PhysicalConnectionHandlingMode) - * - * @since 5.2 - */ - String CONNECTION_HANDLING = "hibernate.connection.handling_mode"; + String CFG_XML_FILE = "hibernate.cfg_xml_file"; + String ORM_XML_FILES = "hibernate.orm_xml_files"; + String HBM_XML_FILES = "hibernate.hbm_xml_files"; + String LOADED_CLASSES = "hibernate.loaded_classes"; /** * Specifies a {@link org.hibernate.context.spi.CurrentSessionContext} for @@ -1188,997 +101,6 @@ public interface AvailableSettings { */ String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class"; - /** - * When enabled, specifies that the generated identifier of an entity is unset - * when the entity is {@linkplain org.hibernate.Session#remove(Object) deleted}. - *

- * By default, generated identifiers are never unset. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyIdentifierRollbackSupport(boolean) - */ - String USE_IDENTIFIER_ROLLBACK = "hibernate.use_identifier_rollback"; - - /** - * When enabled, specifies that Hibernate should attempt to map parameter names - * given in a {@link org.hibernate.procedure.ProcedureCall} or - * {@link jakarta.persistence.StoredProcedureQuery} to named parameters of the - * JDBC {@link java.sql.CallableStatement}. - * - * @see org.hibernate.boot.spi.SessionFactoryOptions#isUseOfJdbcNamedParametersEnabled() - * - * @since 6.0 - */ - String CALLABLE_NAMED_PARAMS_ENABLED = "hibernate.query.proc.callable_named_params_enabled"; - - /** - * Specifies a {@link org.hibernate.query.hql.HqlTranslator} to use for HQL query - * translation. - */ - String SEMANTIC_QUERY_PRODUCER = "hibernate.query.hql.translator"; - - /** - * Specifies a {@link org.hibernate.query.sqm.sql.SqmTranslatorFactory} to use for - * HQL query translation. - */ - String SEMANTIC_QUERY_TRANSLATOR = "hibernate.query.sqm.translator"; - - /** - * Defines the "global" strategy to use for handling HQL and Criteria mutation queries. - * Specifies a {@link org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy}.. - */ - String QUERY_MULTI_TABLE_MUTATION_STRATEGY = "hibernate.query.mutation_strategy"; - - /** - * Defines the "global" strategy to use for handling HQL and Criteria insert queries. - * Specifies a {@link org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy}. - */ - String QUERY_MULTI_TABLE_INSERT_STRATEGY = "hibernate.query.insert_strategy"; - - /** - * When enabled, specifies that named queries be checked during startup. - *

- * By default, named queries are checked at startup. - *

- * Mainly intended for use in test environments. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyNamedQueryCheckingOnStartup(boolean) - */ - String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check"; - - /** - * Enable ordering of update statements by primary key value, for the purpose of more - * efficient JDBC batching - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyOrderingOfUpdates(boolean) - */ - String ORDER_UPDATES = "hibernate.order_updates"; - - /** - * Enable ordering of insert statements by primary key value, for the purpose of more - * efficient JDBC batching. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyOrderingOfInserts(boolean) - */ - String ORDER_INSERTS = "hibernate.order_inserts"; - - /** - * Allows JPA callbacks (via {@link jakarta.persistence.PreUpdate} and friends) to be - * completely disabled. Mostly useful to save some memory when they are not used. - *

- * JPA callbacks are enabled by default. Set this property to {@code false} to disable - * them. - *

- * Experimental and will likely be removed as soon as the memory overhead is resolved. - * - * @see org.hibernate.jpa.event.spi.CallbackType - * - * @since 5.4 - */ - @Incubating - String JPA_CALLBACKS_ENABLED = "hibernate.jpa_callbacks.enabled"; - - /** - * Specifies the default {@linkplain NullPrecedence precedence of null values} in the HQL - * {@code ORDER BY} clause, either {@code none}, {@code first}, or {@code last}. - *

- * The default is {@code none}. - * - * @see NullPrecedence - * @see org.hibernate.boot.SessionFactoryBuilder#applyDefaultNullPrecedence(NullPrecedence) - */ - String DEFAULT_NULL_ORDERING = "hibernate.order_by.default_null_ordering"; - - /** - * When enabled, specifies that JDBC statement warnings should be logged. - *

- * The default is determined by - * {@link org.hibernate.dialect.Dialect#isJdbcLogWarningsEnabledByDefault()}. - * - * @see java.sql.Statement#getWarnings() - * - * @since 5.1 - */ - String LOG_JDBC_WARNINGS = "hibernate.jdbc.log.warnings"; - - /** - * Identifies a {@link org.hibernate.resource.beans.container.spi.BeanContainer} - * to be used. - *

- * Note that for CDI-based containers setting this is not necessary - simply - * pass the {@link jakarta.enterprise.inject.spi.BeanManager} to use via - * {@link #CDI_BEAN_MANAGER} and optionally specify {@link #DELAY_CDI_ACCESS}. - * This setting useful to integrate non-CDI bean containers such as Spring. - * - * @since 5.3 - */ - String BEAN_CONTAINER = "hibernate.resource.beans.container"; - - /** - * Used in conjunction with {@value #BEAN_CONTAINER} when CDI is used. - *

- * By default, to be JPA spec compliant, Hibernate should access the CDI - * {@link jakarta.enterprise.inject.spi.BeanManager} while bootstrapping the - * {@link org.hibernate.SessionFactory}. In some cases however this can lead - * to a chicken/egg situation where the JPA provider immediately accesses the - * {@code BeanManager} when managed beans are awaiting JPA PU injection. - *

- * This setting tells Hibernate to delay accessing until first use. - *

- * This setting has the decided downside that bean config problems will not - * be done at deployment time, but will instead manifest at runtime. For this - * reason, the preferred means for supplying a CDI BeanManager is to provide - * an implementation of - * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager} which - * gives Hibernate a callback when the {@code BeanManager} is ready for use. - * - * @since 5.0.8 - */ - String DELAY_CDI_ACCESS = "hibernate.delay_cdi_access"; - - /** - * Controls whether Hibernate can try to create beans other than converters - * and listeners using CDI. Only meaningful when a CDI {@link #BEAN_CONTAINER container} - * is used. - *

- * By default, Hibernate will only attempt to create converter and listener beans using CDI. - * - * @since 6.2 - */ - String ALLOW_EXTENSIONS_IN_CDI = "hibernate.cdi.extensions"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // c3p0 connection pooling specific settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * A setting prefix used to indicate settings that target the hibernate-c3p0 integration - */ - String C3P0_CONFIG_PREFIX = "hibernate.c3p0"; - - /** - * Maximum size of C3P0 connection pool - */ - String C3P0_MAX_SIZE = "hibernate.c3p0.max_size"; - - /** - * Minimum size of C3P0 connection pool - */ - String C3P0_MIN_SIZE = "hibernate.c3p0.min_size"; - - /** - * Maximum idle time for C3P0 connection pool - */ - String C3P0_TIMEOUT = "hibernate.c3p0.timeout"; - - /** - * Maximum size of C3P0 statement cache - */ - String C3P0_MAX_STATEMENTS = "hibernate.c3p0.max_statements"; - - /** - * Number of connections acquired when pool is exhausted - */ - String C3P0_ACQUIRE_INCREMENT = "hibernate.c3p0.acquire_increment"; - - /** - * Idle time before a C3P0 pooled connection is validated - */ - String C3P0_IDLE_TEST_PERIOD = "hibernate.c3p0.idle_test_period"; - - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // proxool connection pooling specific settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * A setting prefix used to indicate settings that target the hibernate-proxool integration - */ - String PROXOOL_CONFIG_PREFIX = "hibernate.proxool"; - - /** - * Proxool property to configure the Proxool provider using an XML ({@code /path/to/file.xml}) - */ - String PROXOOL_XML = "hibernate.proxool.xml"; - - /** - * Proxool property to configure the Proxool provider using a properties file - * ({@code /path/to/proxool.properties}) - */ - String PROXOOL_PROPERTIES = "hibernate.proxool.properties"; - - /** - * Proxool property to configure the Proxool Provider from an already existing pool - * ({@code true} / {@code false}) - */ - String PROXOOL_EXISTING_POOL = "hibernate.proxool.existing_pool"; - - /** - * Proxool property with the Proxool pool alias to use - * (Required for {@link #PROXOOL_EXISTING_POOL}, {@link #PROXOOL_PROPERTIES}, or - * {@link #PROXOOL_XML}) - */ - String PROXOOL_POOL_ALIAS = "hibernate.proxool.pool_alias"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Second-level cache settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * The {@link org.hibernate.cache.spi.RegionFactory} implementation, either: - *

    - *
  • an instance of {@link org.hibernate.cache.spi.RegionFactory}, - *
  • a {@link Class} implementing {@link org.hibernate.cache.spi.RegionFactory}, or - *
  • he name of a class implementing {@link org.hibernate.cache.spi.RegionFactory}. - *
- *

- * Defaults to {@link NoCachingRegionFactory}, so that caching is disabled. - * - * @see #USE_SECOND_LEVEL_CACHE - */ - String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class"; - - /** - * Specifies the {@link org.hibernate.cache.spi.CacheKeysFactory} to use, either: - *

    - *
  • an instance of {@link org.hibernate.cache.spi.CacheKeysFactory}, - *
  • a {@link Class} implementing {@link org.hibernate.cache.spi.CacheKeysFactory}, - *
  • the name of a class implementing {@link org.hibernate.cache.spi.CacheKeysFactory}, - *
  • {@code "default"} as a short name for {@link org.hibernate.cache.internal.DefaultCacheKeysFactory}, or - *
  • {@code "simple"} as a short name for {@link org.hibernate.cache.internal.SimpleCacheKeysFactory}. - *
- * - * @since 5.2 - * - * @deprecated this is only honored for {@code hibernate-infinispan} - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String CACHE_KEYS_FACTORY = "hibernate.cache.keys_factory"; - - /** - * When enabled, specifies that the second-level cache may be used. - *

- * By default, if the configured {@link org.hibernate.cache.spi.RegionFactory} - * is not the {@link org.hibernate.cache.internal.NoCachingRegionFactory}, then - * the second-level cache is enabled. Otherwise, the second-level cache is disabled. - * - * @see #CACHE_REGION_FACTORY - * @see org.hibernate.boot.SessionFactoryBuilder#applySecondLevelCacheSupport(boolean) - */ - String USE_SECOND_LEVEL_CACHE = "hibernate.cache.use_second_level_cache"; - - /** - * Enable the query cache (disabled by default). - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyQueryCacheSupport(boolean) - */ - String USE_QUERY_CACHE = "hibernate.cache.use_query_cache"; - - /** - * Specifies the {@link org.hibernate.cache.spi.TimestampsCacheFactory} to use. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyTimestampsCacheFactory(TimestampsCacheFactory) - */ - String QUERY_CACHE_FACTORY = "hibernate.cache.query_cache_factory"; - - /** - * The {@code CacheProvider} region name prefix - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyCacheRegionPrefix(String) - */ - String CACHE_REGION_PREFIX = "hibernate.cache.region_prefix"; - - /** - * Optimize interaction with the second-level cache to minimize writes, at the cost - * of an additional read before each write. This setting is useful if writes to the - * cache are much more expensive than reads from the cache, for example, if the cache - * is a distributed cache. - *

- * It's not usually necessary to set this explicitly because, by default, it's set - * to a {@linkplain org.hibernate.boot.SessionFactoryBuilder#applyMinimalPutsForCaching(boolean) - * sensible value} by the second-level cache implementation. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyMinimalPutsForCaching(boolean) - */ - String USE_MINIMAL_PUTS = "hibernate.cache.use_minimal_puts"; - - /** - * Enables the use of structured second-level cache entries. This makes the cache - * entries human-readable, but carries a performance cost. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyStructuredCacheEntries(boolean) - */ - String USE_STRUCTURED_CACHE = "hibernate.cache.use_structured_entries"; - - /** - * Enables the automatic eviction of a bidirectional association's collection - * cache when an element in the {@link jakarta.persistence.ManyToOne} collection - * is added, updated, or removed without properly managing the change on the - * {@link jakarta.persistence.OneToMany} side. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyAutomaticEvictionOfCollectionCaches(boolean) - */ - String AUTO_EVICT_COLLECTION_CACHE = "hibernate.cache.auto_evict_collection_cache"; - - /** - * Enable direct storage of entity references into the second level cache when - * applicable. This is appropriate only for immutable entities. - *

- * By default, entities are always stored in a "disassembled" form, that is, as - * a tuple of attribute values. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyDirectReferenceCaching(boolean) - */ - String USE_DIRECT_REFERENCE_CACHE_ENTRIES = "hibernate.cache.use_reference_entries"; - - - - - - - // Still to categorize - - /** - * When enabled, all database identifiers are quoted. - */ - String GLOBALLY_QUOTED_IDENTIFIERS = "hibernate.globally_quoted_identifiers"; - - /** - * Assuming {@link #GLOBALLY_QUOTED_IDENTIFIERS}, this allows global quoting - * to skip column definitions defined by {@link jakarta.persistence.Column}, - * {@link jakarta.persistence.JoinColumn}, etc. - *

- * JPA states that column definitions are subject to global quoting, so by default - * this setting is {@code false} for JPA compliance. Set to {@code true} to avoid - * explicit column names being quoted due to global quoting (they will still be - * quoted if explicitly quoted in the annotation or XML). - */ - String GLOBALLY_QUOTED_IDENTIFIERS_SKIP_COLUMN_DEFINITIONS = "hibernate.globally_quoted_identifiers_skip_column_definitions"; - - /** - * Enable nullability checking, raises an exception if an attribute marked as - * {@linkplain jakarta.persistence.Basic#optional() not null} is null at runtime. - *

- * Defaults to disabled if Bean Validation is present in the classpath and - * annotations are used, or enabled otherwise. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyNullabilityChecking(boolean) - */ - String CHECK_NULLABILITY = "hibernate.check_nullability"; - - /** - * Selects a bytecode enhancement library. - *

- * At present only bytebuddy is supported, bytebuddy being the default since version 5.3. - */ - String BYTECODE_PROVIDER = "hibernate.bytecode.provider"; - - String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance"; - - /** - * When a generator specifies an increment-size and an optimizer was not explicitly - * specified, which of the "pooled" optimizers should be preferred? Can specify an - * optimizer short name or the name of a class which implements - * {@link org.hibernate.id.enhanced.Optimizer}. - */ - String PREFERRED_POOLED_OPTIMIZER = "hibernate.id.optimizer.pooled.preferred"; - - /** - * When enabled, specifies that {@linkplain QueryPlan query plans} should be - * {@linkplain org.hibernate.query.spi.QueryInterpretationCache cached}. - *

- * By default, the query plan cache is disabled, unless one of the configuration - * properties {@value #QUERY_PLAN_CACHE_MAX_SIZE} or - * {@value #QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE} is set. - */ - String QUERY_PLAN_CACHE_ENABLED = "hibernate.query.plan_cache_enabled"; - - /** - * The maximum number of entries in the - * {@linkplain org.hibernate.query.spi.QueryInterpretationCache - * query interpretation cache}. - *

- * The default maximum is - * {@value org.hibernate.query.spi.QueryEngine#DEFAULT_QUERY_PLAN_MAX_COUNT}. - * - * @see org.hibernate.query.spi.QueryInterpretationCache - */ - String QUERY_PLAN_CACHE_MAX_SIZE = "hibernate.query.plan_cache_max_size"; - - /** - * The maximum number of {@link org.hibernate.query.ParameterMetadata} instances - * maintained by the {@link org.hibernate.query.spi.QueryInterpretationCache}. - *

- * - * @deprecated this setting is not currently used - */ - @Deprecated(since="6.0") - String QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE = "hibernate.query.plan_parameter_metadata_max_size"; - - /** - * When enabled, specifies that Hibernate should not use contextual LOB creation. - * - * @see org.hibernate.engine.jdbc.LobCreator - * @see org.hibernate.engine.jdbc.LobCreationContext - */ - String NON_CONTEXTUAL_LOB_CREATION = "hibernate.jdbc.lob.non_contextual_creation"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // SchemaManagementTool settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * Setting to perform {@link org.hibernate.tool.schema.spi.SchemaManagementTool} - * actions automatically as part of the {@link org.hibernate.SessionFactory} - * lifecycle. Valid options are enumerated by {@link org.hibernate.tool.schema.Action}. - *

- * Interpreted in combination with {@link #JAKARTA_HBM2DDL_DATABASE_ACTION} and - * {@link #JAKARTA_HBM2DDL_SCRIPTS_ACTION}. If no value is specified, the default - * is {@link org.hibernate.tool.schema.Action#NONE "none"}. - * - * @see org.hibernate.tool.schema.Action - */ - String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto"; - - /** - * @deprecated Use {@link #JAKARTA_HBM2DDL_DATABASE_ACTION} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_DATABASE_ACTION = "javax.persistence.schema-generation.database.action"; - - /** - * @deprecated Use {@link #JAKARTA_HBM2DDL_SCRIPTS_ACTION} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_SCRIPTS_ACTION = "javax.persistence.schema-generation.scripts.action"; - - /** - * @deprecated Use {@link #JAKARTA_HBM2DDL_CONNECTION} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_CONNECTION = "javax.persistence.schema-generation-connection"; - - /** - * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_CREATE_SOURCE} instead - * @see org.hibernate.tool.schema.SourceType - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_CREATE_SOURCE = "javax.persistence.schema-generation.create-source"; - - /** - * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_DROP_SOURCE}. - * @see org.hibernate.tool.schema.SourceType - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_DROP_SOURCE = "javax.persistence.schema-generation.drop-source"; - - /** - * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE} - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_CREATE_SCRIPT_SOURCE = "javax.persistence.schema-generation.create-script-source"; - - /** - * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE} - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_DROP_SCRIPT_SOURCE = "javax.persistence.schema-generation.drop-script-source"; - - /** - * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET} - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_SCRIPTS_CREATE_TARGET = "javax.persistence.schema-generation.scripts.create-target"; - - /** - * For cases where the {@value #HBM2DDL_SCRIPTS_ACTION} value indicates that schema commands - * should be written to DDL script file, specifies if schema commands should be appended to - * the end of the file rather than written at the beginning of the file. - *

- * Values are: {@code true} for appending schema commands to the end of the file, {@code false} - * for writing schema commands at the beginning. - *

- * The default value is {@code true} - */ - String HBM2DDL_SCRIPTS_CREATE_APPEND = "hibernate.hbm2ddl.schema-generation.script.append"; - - /** - * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_SCRIPTS_DROP_TARGET} - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_SCRIPTS_DROP_TARGET = "javax.persistence.schema-generation.scripts.drop-target"; - - /** - * Specifies a comma-separated list of file names of scripts containing SQL DML statements that - * should be executed after schema export completes. The order of the scripts is significant, - * with the first script in the list being executed first. - *

- * The scripts are only executed if the schema is created by Hibernate, that is, if - * {@value #HBM2DDL_AUTO} is set to {@code create} or {@code create-drop}. - *

- * The default value is {@code /import.sql}. - *

- * The JPA-standard setting {@link #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE} is now preferred. - */ - String HBM2DDL_IMPORT_FILES = "hibernate.hbm2ddl.import_files"; - - /** - * @deprecated Use {@link #JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_LOAD_SCRIPT_SOURCE = "javax.persistence.sql-load-script-source"; - - /** - * The {@link org.hibernate.tool.schema.spi.SqlScriptCommandExtractor} implementation - * to use for parsing source/import files specified by {@link #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE}, - * {@link #JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE} or {@link #HBM2DDL_IMPORT_FILES}. Either: - *

    - *
  • an instance of {@link org.hibernate.tool.schema.spi.SqlScriptCommandExtractor}, - *
  • a {@link Class} object representing a class that implements {@code SqlScriptCommandExtractor}, - * or - *
  • the name of a class that implements {@code SqlScriptCommandExtractor}. - *
- *

- * The correct extractor to use depends on the format of the SQL script: - *

    - *
  • if the script has one complete SQL statement per line, use - * {@link org.hibernate.tool.schema.internal.script.SingleLineSqlScriptExtractor}, or - *
  • if a script contains statements spread over multiple lines, use - * {@link org.hibernate.tool.schema.internal.script.MultiLineSqlScriptExtractor}. - *
- *

- * The default value is {@code org.hibernate.tool.schema.internal.script.SingleLineSqlScriptExtractor}. - * - * @see org.hibernate.tool.schema.internal.script.SingleLineSqlScriptExtractor - * @see org.hibernate.tool.schema.internal.script.MultiLineSqlScriptExtractor - */ - String HBM2DDL_IMPORT_FILES_SQL_EXTRACTOR = "hibernate.hbm2ddl.import_files_sql_extractor"; - - /** - * Specifies whether to automatically create also the database schema/catalog. - * The default is false. - * - * @since 5.0 - */ - String HBM2DDL_CREATE_NAMESPACES = "hibernate.hbm2ddl.create_namespaces"; - - /** - * @deprecated Use {@link #JAKARTA_HBM2DDL_CREATE_SCHEMAS} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String HBM2DDL_CREATE_SCHEMAS = "javax.persistence.create-database-schemas"; - - /** - * Specifies what type of schema tooling action should be performed against the - * database specified using either {@value #JAKARTA_HBM2DDL_CONNECTION} or the - * configured {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} - * for the {@link org.hibernate.SessionFactory}. - *

- * Valid options are enumerated by {@link org.hibernate.tool.schema.Action}. - *

- * This setting takes precedence over {@value #HBM2DDL_AUTO}. - *

- * If no value is specified, the default is - * {@link org.hibernate.tool.schema.Action#NONE "none"}. - * - * @see org.hibernate.tool.schema.Action - * @see #JAKARTA_HBM2DDL_CONNECTION - * @see #JAKARTA_JDBC_URL - */ - String JAKARTA_HBM2DDL_DATABASE_ACTION = "jakarta.persistence.schema-generation.database.action"; - - /** - * Specifies what type of schema tooling action should be written to script files. - *

- * Valid options are enumerated by {@link org.hibernate.tool.schema.Action}. - *

- * The script file is identified using {@value #JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET}. - *

- * If no value is specified, the default is - * {@link org.hibernate.tool.schema.Action#NONE "none"}. - * - * @see org.hibernate.tool.schema.Action - * @see #JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET - * @see #JAKARTA_HBM2DDL_SCRIPTS_DROP_TARGET - */ - String JAKARTA_HBM2DDL_SCRIPTS_ACTION = "jakarta.persistence.schema-generation.scripts.action"; - - /** - * Allows passing a specific {@link java.sql.Connection} instance to be used by - * {@link org.hibernate.tool.schema.spi.SchemaManagementTool} for the purpose of - * determining the {@link org.hibernate.dialect.Dialect}, and for performing - * {@link #JAKARTA_HBM2DDL_DATABASE_ACTION database actions} if requested. - *

- * For {@code Dialect} resolution, {@value #JAKARTA_HBM2DDL_DB_NAME} and, optionally, - * {@value JAKARTA_HBM2DDL_DB_VERSION}, {@value #JAKARTA_HBM2DDL_DB_MAJOR_VERSION}, - * and {@value #JAKARTA_HBM2DDL_DB_MINOR_VERSION} can be used instead - * - * @see #JAKARTA_HBM2DDL_DB_NAME - * @see #JAKARTA_HBM2DDL_DB_VERSION - * @see #JAKARTA_HBM2DDL_DB_MAJOR_VERSION - * @see #JAKARTA_HBM2DDL_DB_MINOR_VERSION - */ - String JAKARTA_HBM2DDL_CONNECTION = "jakarta.persistence.schema-generation-connection"; - - /** - * Specifies the name of the database vendor (as would be reported by - * {@link java.sql.DatabaseMetaData#getDatabaseProductName}) for the purpose of - * determining the {@link org.hibernate.dialect.Dialect} to use. - *

- * For cases when the name of the database vendor is not enough alone, a combination - * of {@value JAKARTA_HBM2DDL_DB_VERSION}, {@value #JAKARTA_HBM2DDL_DB_MAJOR_VERSION} - * {@value #JAKARTA_HBM2DDL_DB_MINOR_VERSION} can be used instead - * - * @see #JAKARTA_HBM2DDL_DB_VERSION - * @see #JAKARTA_HBM2DDL_DB_MAJOR_VERSION - * @see #JAKARTA_HBM2DDL_DB_MINOR_VERSION - * - * @implSpec {@link #JAKARTA_HBM2DDL_DATABASE_ACTION database actions} are not - * available when supplying just the name and versions - */ - String JAKARTA_HBM2DDL_DB_NAME = "jakarta.persistence.database-product-name"; - - /** - * Used in conjunction with {@value #JAKARTA_HBM2DDL_DB_NAME} for the purpose of - * determining the {@link org.hibernate.dialect.Dialect} to use when the name does - * not provide enough detail. - *

- * The value is expected to match what would be returned from - * {@link java.sql.DatabaseMetaData#getDatabaseProductVersion()}) for the - * underlying database. - * - * @see #JAKARTA_HBM2DDL_DB_NAME - */ - String JAKARTA_HBM2DDL_DB_VERSION = "jakarta.persistence.database-product-version"; - - /** - * Used in conjunction with {@value #JAKARTA_HBM2DDL_DB_NAME} for the purpose of - * determining the {@link org.hibernate.dialect.Dialect} to use when the name does - * not provide enough detail. - *

- * The value is expected to match what would be returned from - * {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion()}) for the underlying - * database. - * - * @see #JAKARTA_HBM2DDL_DB_NAME - */ - String JAKARTA_HBM2DDL_DB_MAJOR_VERSION = "jakarta.persistence.database-major-version"; - - /** - * Used in conjunction with {@value #JAKARTA_HBM2DDL_DB_NAME} for the purpose of - * determining the {@link org.hibernate.dialect.Dialect} to use when the name does - * not provide enough detail. - *

- * The value is expected to match what would be returned from - * {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion()}) for the underlying - * database. - * - * @see #JAKARTA_HBM2DDL_DB_NAME - */ - String JAKARTA_HBM2DDL_DB_MINOR_VERSION = "jakarta.persistence.database-minor-version"; - - /** - * Specifies whether schema generation commands for schema creation are to be determined - * based on object/relational mapping metadata, DDL scripts, or a combination of the two. - * See {@link org.hibernate.tool.schema.SourceType} for the list of legal values. - *

- * If no value is specified, a default is inferred as follows: - *

    - *
  • if source scripts are specified via {@value #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE}, - * then {@link org.hibernate.tool.schema.SourceType#SCRIPT "script"} is assumed, or - *
  • otherwise, {@link org.hibernate.tool.schema.SourceType#SCRIPT "metadata"} is - * assumed. - *
- * - * @see org.hibernate.tool.schema.SourceType - */ - String JAKARTA_HBM2DDL_CREATE_SOURCE = "jakarta.persistence.schema-generation.create-source"; - - /** - * Specifies whether schema generation commands for schema dropping are to be determined - * based on object/relational mapping metadata, DDL scripts, or a combination of the two. - * See {@link org.hibernate.tool.schema.SourceType} for the list of legal values. - *

- * If no value is specified, a default is inferred as follows: - *

    - *
  • if source scripts are specified via {@value #JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE}, - * then {@linkplain org.hibernate.tool.schema.SourceType#SCRIPT "script"} is assumed, or - *
  • otherwise, {@linkplain org.hibernate.tool.schema.SourceType#SCRIPT "metadata"} - * is assumed. - *
- * - * @see org.hibernate.tool.schema.SourceType - */ - String JAKARTA_HBM2DDL_DROP_SOURCE = "jakarta.persistence.schema-generation.drop-source"; - - /** - * Specifies the CREATE script file as either a {@link java.io.Reader} configured for reading - * the DDL script file or a string designating a file {@link java.net.URL} for the DDL script. - *

- * Hibernate historically also accepted {@link #HBM2DDL_IMPORT_FILES} for a similar purpose. - * This setting is now preferred. - * - * @see #JAKARTA_HBM2DDL_CREATE_SOURCE - * @see #HBM2DDL_IMPORT_FILES - */ - String JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE = "jakarta.persistence.schema-generation.create-script-source"; - - /** - * Specifies the DROP script file as either a {@link java.io.Reader} configured for reading - * the DDL script file or a string designating a file {@link java.net.URL} for the DDL script. - * - * @see #JAKARTA_HBM2DDL_DROP_SOURCE - */ - String JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE = "jakarta.persistence.schema-generation.drop-script-source"; - - /** - * For cases where {@value #JAKARTA_HBM2DDL_SCRIPTS_ACTION} indicates that schema creation - * commands should be written to a script file, this setting specifies either a - * {@link java.io.Writer} configured for output of the DDL script or a string specifying - * the file URL for the DDL script. - * - * @see #JAKARTA_HBM2DDL_SCRIPTS_ACTION - */ - String JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET = "jakarta.persistence.schema-generation.scripts.create-target"; - - /** - * For cases where {@value #JAKARTA_HBM2DDL_SCRIPTS_ACTION} indicates that schema - * drop commands should be written to a script file, this setting specifies either a - * {@link java.io.Writer} configured for output of the DDL script or a string - * specifying the file URL for the DDL script. - * - * @see #JAKARTA_HBM2DDL_SCRIPTS_ACTION - */ - String JAKARTA_HBM2DDL_SCRIPTS_DROP_TARGET = "jakarta.persistence.schema-generation.scripts.drop-target"; - - /** - * JPA-standard variant of {@link #HBM2DDL_IMPORT_FILES} for specifying a database - * initialization script to be run as part of schema-export - *

- * Specifies a {@link java.io.Reader} configured for reading of the SQL load script - * or a string designating the {@link java.net.URL} for the SQL load script. - */ - String JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE = "jakarta.persistence.sql-load-script-source"; - - /** - * The JPA variant of {@link #HBM2DDL_CREATE_NAMESPACES} used to specify whether database - * schemas used in the mapping model should be created on export in addition to creating - * the tables, sequences, etc. - *

- * The default is {@code false}, meaning to not create schemas - */ - String JAKARTA_HBM2DDL_CREATE_SCHEMAS = "jakarta.persistence.create-database-schemas"; - - /** - * Used to specify the {@link org.hibernate.tool.schema.spi.SchemaFilterProvider} to be - * used by create, drop, migrate and validate operations on the database schema. A - * {@code SchemaFilterProvider} provides filters that can be used to limit the scope of - * these operations to specific namespaces, tables and sequences. All objects are - * included by default. - * - * @since 5.1 - */ - String HBM2DDL_FILTER_PROVIDER = "hibernate.hbm2ddl.schema_filter_provider"; - - /** - * Setting to choose the strategy used to access the JDBC Metadata. - *

- * Valid options are defined by {@link org.hibernate.tool.schema.JdbcMetadaAccessStrategy}. - * {@link org.hibernate.tool.schema.JdbcMetadaAccessStrategy#GROUPED} is the default. - * - * @see org.hibernate.tool.schema.JdbcMetadaAccessStrategy - */ - String HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY = "hibernate.hbm2ddl.jdbc_metadata_extraction_strategy"; - - /** - * Identifies the delimiter to use to separate schema management statements in script - * outputs. - *

- * The default value is {@code ;}. - */ - String HBM2DDL_DELIMITER = "hibernate.hbm2ddl.delimiter"; - - /** - * The name of the charset used by the schema generation resource. - *

- * By default, the JVM default charset is used. - * - * @since 5.2.3 - */ - String HBM2DDL_CHARSET_NAME = "hibernate.hbm2ddl.charset_name"; - - /** - * When enabled, specifies that the schema migration tool should halt on any error, - * terminating the bootstrap process. - * - * @since 5.2.4 - */ - String HBM2DDL_HALT_ON_ERROR = "hibernate.hbm2ddl.halt_on_error"; - - /** - * Used with the {@link jakarta.persistence.ConstraintMode#PROVIDER_DEFAULT} - * strategy for foreign key mapping. - *

- * Valid values are {@link jakarta.persistence.ConstraintMode#CONSTRAINT} and - * {@link jakarta.persistence.ConstraintMode#NO_CONSTRAINT}. - *

- * The default value is {@link jakarta.persistence.ConstraintMode#CONSTRAINT}. - * - * @since 5.4 - */ - String HBM2DDL_DEFAULT_CONSTRAINT_MODE = "hibernate.hbm2ddl.default_constraint_mode"; - - /** - * Setting to identify a {@link org.hibernate.CustomEntityDirtinessStrategy} to use. - * May specify either a class name or an instance. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyCustomEntityDirtinessStrategy(CustomEntityDirtinessStrategy) - */ - String CUSTOM_ENTITY_DIRTINESS_STRATEGY = "hibernate.entity_dirtiness_strategy"; - - /** - * The {@link org.hibernate.annotations.Where @Where} annotation specifies a - * restriction on the table rows which are visible as entity class instances or - * collection elements. - *

- * This setting controls whether the restriction applied to an entity should be - * applied to association fetches (for one-to-one, many-to-one, one-to-many, and - * many-to-many associations) which target the entity. - * - * @apiNote The setting is very misnamed - it applies across all entity associations, - * not only to collections. - * - * @implSpec Enabled ({@code true}) by default, meaning the restriction is applied. - * When this setting is explicitly disabled ({@code false}), the restriction - * is not applied. - * - * @deprecated Originally added as a backwards compatibility flag - */ - @Remove @Deprecated( forRemoval = true, since = "6.2" ) - String USE_ENTITY_WHERE_CLAUSE_FOR_COLLECTIONS = "hibernate.use_entity_where_clause_for_collections"; - - /** - * Specifies a {@link org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider} - * to use. Since {@code MultiTenantConnectionProvider} is also a service, it may be configured - * directly via the {@link org.hibernate.boot.registry.StandardServiceRegistryBuilder}. - * - * @since 4.1 - */ - String MULTI_TENANT_CONNECTION_PROVIDER = "hibernate.multi_tenant_connection_provider"; - - /** - * Specifies a {@link org.hibernate.context.spi.CurrentTenantIdentifierResolver} to use, - * either: - *

    - *
  • an instance of {@code CurrentTenantIdentifierResolver}, - *
  • a {@link Class} representing an class that implements {@code CurrentTenantIdentifierResolver}, or - *
  • the name of a class that implements {@code CurrentTenantIdentifierResolver}. - *
- * - * @see org.hibernate.boot.SessionFactoryBuilder#applyCurrentTenantIdentifierResolver(CurrentTenantIdentifierResolver) - * - * @since 4.1 - */ - String MULTI_TENANT_IDENTIFIER_RESOLVER = "hibernate.tenant_identifier_resolver"; - - /** - * Specifies an {@link org.hibernate.Interceptor} implementation associated with - * the {@link org.hibernate.SessionFactory} and propagated to each {@code Session} - * created from the {@code SessionFactory}. Either: - *
    - *
  • an instance of {@code Interceptor}, - *
  • a {@link Class} representing a class that implements {@code Interceptor}, or - *
  • the name of a class that implements {@code Interceptor}. - *
- *

- * This setting identifies an {@code Interceptor} which is effectively a singleton - * across all the sessions opened from the {@code SessionFactory} to which it is - * applied; the same instance will be passed to each {@code Session}. If there - * should be a separate instance of {@code Interceptor} for each {@code Session}, - * use {@link #SESSION_SCOPED_INTERCEPTOR} instead. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyInterceptor(Interceptor) - * - * @since 5.0 - */ - String INTERCEPTOR = "hibernate.session_factory.interceptor"; - - /** - * Specifies an {@link org.hibernate.Interceptor} implementation associated with - * the {@link org.hibernate.SessionFactory} and propagated to each {@code Session} - * created from the {@code SessionFactory}. Either: - *

    - *
  • a {@link Class} representing a class that implements {@code Interceptor}, - *
  • the name of a class that implements {@code Interceptor}, or - *
  • an instance of {@link Supplier} used to obtain the interceptor. - *
- *

- * Note that this setting cannot specify an {@code Interceptor} instance. - *

- * This setting identifies an {@code Interceptor} implementation that is to be - * applied to every {@code Session} opened from the {@code SessionFactory}, but - * unlike {@link #INTERCEPTOR}, a separate instance created for each {@code Session}. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyStatelessInterceptor(Class) - * @see org.hibernate.boot.SessionFactoryBuilder#applyStatelessInterceptor(Supplier) - * - * @since 5.2 - */ - String SESSION_SCOPED_INTERCEPTOR = "hibernate.session_factory.session_scoped_interceptor"; - - /** - * Specifies a {@link org.hibernate.resource.jdbc.spi.StatementInspector} - * implementation associated with the {@link org.hibernate.SessionFactory}, - * either: - *

    - *
  • an instance of {@code StatementInspector}, - *
  • a {@link Class} representing an class that implements {@code StatementInspector}, or - *
  • the name of a class that implements {@code StatementInspector}. - *
- * - * @see org.hibernate.boot.SessionFactoryBuilder#applyStatementInspector(StatementInspector) - * - * @since 5.0 - */ - String STATEMENT_INSPECTOR = "hibernate.session_factory.statement_inspector"; - - /** - * Allows a detached proxy or lazy collection to be fetched even when not - * associated with an open persistence context, by creating a temporary - * persistence context when the proxy or collection is accessed. This - * behavior is not recommended, since it can easily break transaction - * isolation or lead to data aliasing. It is therefore disabled by default. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyLazyInitializationOutsideTransaction(boolean) - */ - String ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans"; - - /** - * Specifies the {@link org.hibernate.loader.BatchFetchStyle} to use, - * either the name of a {code BatchFetchStyle} instance, or an instance - * of {@code BatchFetchStyle}. - * - * @deprecated An appropriate batch-fetch style is selected automatically - */ - @Deprecated(since = "6.0") - @SuppressWarnings("DeprecatedIsStillUsed") - String BATCH_FETCH_STYLE = "hibernate.batch_fetch_style"; - /** * Controls how {@linkplain org.hibernate.loader.ast.spi.Loader entity loaders} * are created. @@ -2201,144 +123,6 @@ public interface AvailableSettings { */ String DELAY_ENTITY_LOADER_CREATIONS = "hibernate.loader.delay_entity_loader_creations"; - /** - * A transaction can be rolled back by another thread ("tracking by thread") - * -- not the original application. Examples of this include a JTA - * transaction timeout handled by a background reaper thread. The ability - * to handle this situation requires checking the Thread ID every time - * Session is called. This can certainly have performance considerations. - *

- * Default is {@code true} (enabled). - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyJtaTrackingByThread(boolean) - */ - String JTA_TRACK_BY_THREAD = "hibernate.jta.track_by_thread"; - - /** - * If enabled, allows schema update and validation to support synonyms. Due - * to the possibility that this would return duplicate tables (especially in - * Oracle), this is disabled by default. - */ - String ENABLE_SYNONYMS = "hibernate.synonyms"; - - /** - * Specifies a comma-separated list of extra table types, in addition to the - * default types {@code "TABLE"} and {@code "VIEW"}, to recognize as physical - * tables when performing schema update, creation and validation. - * - * @since 5.0 - */ - String EXTRA_PHYSICAL_TABLE_TYPES = "hibernate.hbm2ddl.extra_physical_table_types"; - - /** - * Unique columns and unique keys both use unique constraints in most dialects. - * The schema exporter must create these constraints, but database support for - * finding existing constraints is extremely inconsistent. Worse, unique constraints - * without explicit names are assigned names with randomly generated characters. - *

- * Therefore, select from these strategies: - *

    - *
  • {@link org.hibernate.tool.schema.UniqueConstraintSchemaUpdateStrategy#DROP_RECREATE_QUIETLY - * DROP_RECREATE_QUIETLY}: - * Attempt to drop, then (re-)create each unique constraint, - * ignoring any exceptions thrown. - * This is the default. - *
  • {@link org.hibernate.tool.schema.UniqueConstraintSchemaUpdateStrategy#RECREATE_QUIETLY - * RECREATE_QUIETLY}: - * attempt to (re-)create unique constraints, - * ignoring exceptions thrown if the constraint already existed. - *
  • {@link org.hibernate.tool.schema.UniqueConstraintSchemaUpdateStrategy#SKIP - * SKIP}: - * do not attempt to create unique constraints on a schema update. - *
- */ - String UNIQUE_CONSTRAINT_SCHEMA_UPDATE_STRATEGY = "hibernate.schema_update.unique_constraint_strategy"; - - /** - * When enabled, specifies that {@linkplain org.hibernate.stat.Statistics statistics} - * should be collected. - * - * @see org.hibernate.boot.SessionFactoryBuilder#applyStatisticsSupport(boolean) - */ - String GENERATE_STATISTICS = "hibernate.generate_statistics"; - - /** - * Specifies a duration in milliseconds defining the minimum query execution time that - * characterizes a "slow" query. Any SQL query which takes longer than this amount of - * time to execute will be logged. - *

- * A value of {@code 0}, the default, disables logging of "slow" queries. - * - * @see org.hibernate.stat.Statistics#getSlowQueries() - */ - String LOG_SLOW_QUERY = "hibernate.log_slow_query"; - - /** - * Controls whether {@linkplain org.hibernate.stat.SessionStatistics session metrics} - * should be {@linkplain org.hibernate.engine.internal.StatisticalLoggingSessionEventListener - * logged} for any session in which statistics are being collected. - *

- * By default, logging of session metrics is disabled unless {@link #GENERATE_STATISTICS} - * is enabled. - */ - String LOG_SESSION_METRICS = "hibernate.session.events.log"; - - /** - * Defines a default {@link org.hibernate.SessionEventListener} to be applied to - * newly-opened {@link org.hibernate.Session}s. - */ - String AUTO_SESSION_EVENTS_LISTENER = "hibernate.session.events.auto"; - - /** - * Enable instantiation of composite/embedded objects when all attribute values - * are {@code null}. The default (and historical) behavior is that a {@code null} - * reference will be used to represent the composite value when all of its - * attributes are {@code null}. - * - * @apiNote This is an experimental feature that has known issues. It should not - * be used in production until it is stabilized. See Hibernate JIRA issue - * HHH-11936 for details. - * - * @deprecated It makes no sense at all to enable this at the global level for a - * persistence unit. If anything, it could be a setting specific to - * a given embeddable class. But, four years after the introduction of - * this feature, it's still marked experimental and has multiple known - * unresolved bugs. It's therefore time for those who advocated for - * this feature to accept defeat. - * - * @since 5.1 - */ - @Incubating - @Deprecated(since = "6") - String CREATE_EMPTY_COMPOSITES_ENABLED = "hibernate.create_empty_composites.enabled"; - - /** - * When enabled, allows access to the {@link org.hibernate.Transaction} even when - * using a JTA for transaction management. - *

- * Values are {@code true}, which grants access, and {@code false}, which does not. - *

- * The default behavior is to allow access unless Hibernate is bootstrapped via JPA. - */ - String ALLOW_JTA_TRANSACTION_ACCESS = "hibernate.jta.allowTransactionAccess"; - - /** - * When enabled, allows update operations outside a transaction. - *

- * Since version 5.2 Hibernate conforms with the JPA specification and disallows - * flushing any update outside a transaction. - *

- * Values are {@code true}, which allows flushing outside a transaction, and - * {@code false}, which does not. - *

- * The default behavior is to disallow update operations outside a transaction. - * - * @see org.hibernate.boot.SessionFactoryBuilder#allowOutOfTransactionUpdateOperations(boolean) - * - * @since 5.2 - */ - String ALLOW_UPDATE_OUTSIDE_TRANSACTION = "hibernate.allow_update_outside_transaction"; - /** * When enabled, allows calls to {@link jakarta.persistence.EntityManager#refresh(Object)} * and {@link org.hibernate.Session#refresh(Object)} on a detached entity instance. @@ -2353,7 +137,6 @@ public interface AvailableSettings { * @since 5.2 */ String ALLOW_REFRESH_DETACHED_ENTITY = "hibernate.allow_refresh_detached_entity"; - /** * Setting that specifies how Hibernate will respond when multiple representations of * the same persistent entity ("entity copy") are detected while merging. @@ -2386,764 +169,39 @@ public interface AvailableSettings { String MERGE_ENTITY_COPY_OBSERVER = "hibernate.event.merge.entity_copy_observer"; /** - * By default, a {@linkplain jakarta.persistence.criteria.CriteriaBuilder criteria - * query} produces SQL with a JDBC bind parameter for any value specified via the - * criteria query API, except when the value is passed via - * {@link jakarta.persistence.criteria.CriteriaBuilder#literal(Object)}, in which - * case the value is "inlined" as a SQL literal. - *

- * This setting may be used to override this default behavior: - *

    - *
  • the {@link org.hibernate.query.criteria.ValueHandlingMode#BIND "bind"} - * mode uses bind parameters to pass such values to JDBC, but - *
  • the {@link org.hibernate.query.criteria.ValueHandlingMode#INLINE "inline"} - * mode inlines values as SQL literals. - *
- *

- * In both modes: - *

    - *
  • values specified using {@code literal()} are inlined, and - *
  • values specified using - * {@link jakarta.persistence.criteria.CriteriaBuilder#parameter(Class)} to create a - * {@link jakarta.persistence.criteria.ParameterExpression criteria parameter} and - * {@link jakarta.persistence.Query#setParameter(jakarta.persistence.Parameter,Object)} - * to specify its argument are passed to JDBC using a bind parameter. - *
- *

- * The default mode is {@link org.hibernate.query.criteria.ValueHandlingMode#BIND}. + * When enabled, specifies that the persistent context should be discarded when either + * {@link org.hibernate.Session#close()} or {@link jakarta.persistence.EntityManager#close()} + * is called. * - * @since 6.0.0 - * - * @see org.hibernate.query.criteria.ValueHandlingMode - * @see jakarta.persistence.criteria.CriteriaBuilder#literal(Object) - * @see jakarta.persistence.criteria.CriteriaBuilder#parameter(Class) - * @see org.hibernate.query.criteria.HibernateCriteriaBuilder#value(Object) + * @settingDefault {@code false} (not discarded) per the JPA specification. */ - String CRITERIA_VALUE_HANDLING_MODE = "hibernate.criteria.value_handling_mode"; + String DISCARD_PC_ON_CLOSE = "hibernate.discard_pc_on_close"; /** - * When enabled, specifies that {@linkplain org.hibernate.query.Query queries} - * created via {@link jakarta.persistence.EntityManager#createQuery(CriteriaQuery)}, - * {@link jakarta.persistence.EntityManager#createQuery(CriteriaUpdate)} or - * {@link jakarta.persistence.EntityManager#createQuery(CriteriaDelete)} must - * create a copy of the passed criteria query object such that the resulting - * {@link jakarta.persistence.Query} object is not affected by mutation of the - * original {@linkplain CriteriaQuery criteria query}. - *

- * If disabled, it's assumed that the client does not mutate the criteria query - * after calling {@code createQuery()}. Thus, in the interest of performance, no - * copy is created. - *

- * The default behavior depends on how Hibernate is bootstrapped: - *

    - *
  • When bootstrapping Hibernate through the native bootstrap APIs, this setting - * is disabled, that is, no copy of the criteria query object is made. - *
  • When bootstrapping Hibernate through the JPA SPI, this setting is enabled so - * that criteria query objects are copied, as required by the JPA specification. - *
+ * When enabled, specifies that the generated identifier of an entity is unset + * when the entity is {@linkplain org.hibernate.Session#remove(Object) deleted}. * - * @since 6.0 + * @settingDefault {@code false} - generated identifiers are not unset + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyIdentifierRollbackSupport(boolean) */ - String CRITERIA_COPY_TREE = "hibernate.criteria.copy_tree"; + String USE_IDENTIFIER_ROLLBACK = "hibernate.use_identifier_rollback"; /** - * Specifies a default value for all {@link org.hibernate.jpa.spi.JpaCompliance} - * flags. Each individual flag may still be overridden by explicitly specifying - * its specific configuration property. + * Setting to identify a {@link org.hibernate.CustomEntityDirtinessStrategy} to use. + * May specify either a class name or an instance. * - * @see #JPA_TRANSACTION_COMPLIANCE - * @see #JPA_QUERY_COMPLIANCE - * @see #JPA_LIST_COMPLIANCE - * @see #JPA_ORDER_BY_MAPPING_COMPLIANCE - * @see #JPA_CLOSED_COMPLIANCE - * @see #JPA_PROXY_COMPLIANCE - * @see #JPA_CACHING_COMPLIANCE - * @see #JPA_ID_GENERATOR_GLOBAL_SCOPE_COMPLIANCE - * @see #JPA_LOAD_BY_ID_COMPLIANCE - * - * @since 6.0 + * @see org.hibernate.boot.SessionFactoryBuilder#applyCustomEntityDirtinessStrategy(CustomEntityDirtinessStrategy) */ - String JPA_COMPLIANCE = "hibernate.jpa.compliance"; + String CUSTOM_ENTITY_DIRTINESS_STRATEGY = "hibernate.entity_dirtiness_strategy"; /** - * When enabled, specifies that the Hibernate {@link org.hibernate.Transaction} - * should behave according to the semantics defined by the JPA specification for - * an {@link jakarta.persistence.EntityTransaction}. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isJpaTransactionComplianceEnabled() - * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaTransactionCompliance(boolean) - * - * @since 5.3 + * Event listener configuration properties follow the pattern + * {@code hibernate.event.listener.eventType packageName.ClassName1, packageName.ClassName2} */ - String JPA_TRANSACTION_COMPLIANCE = "hibernate.jpa.compliance.transaction"; + String EVENT_LISTENER_PREFIX = "hibernate.event.listener"; /** - * When enabled, specifies that every {@linkplain org.hibernate.query.Query query} - * must strictly follow the specified behavior of {@link jakarta.persistence.Query}. - * The affects JPQL queries, criteria queries, and native SQL queries. - *

- * This setting modifies the behavior of the JPQL query translator, and of the - * {@code Query} interface itself. In particular, it forces all methods of - * {@code Query} to throw the exception types defined by the JPA specification. - *

- * If enabled, any deviations from the JPQL specification results in an exception. - * Therefore, this setting is not recommended, since it prohibits the use of many - * useful features of HQL. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isJpaQueryComplianceEnabled() - * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaQueryCompliance(boolean) - * - * @since 5.3 - */ - String JPA_QUERY_COMPLIANCE = "hibernate.jpa.compliance.query"; - - /** - * Controls whether Hibernate should treat what it would usually consider a - * {@linkplain org.hibernate.collection.spi.PersistentBag "bag"}, that is, a - * list with no index column, whose element order is not persistent, as a true - * {@link org.hibernate.collection.spi.PersistentList list} with an index column - * and a persistent element order. - *

- * If enabled, Hibernate will recognize it as a list where the - * {@link jakarta.persistence.OrderColumn} annotation is simply missing - * (and its defaults will apply). - * - * @see org.hibernate.jpa.spi.JpaCompliance#isJpaListComplianceEnabled() - * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaListCompliance(boolean) - * - * @since 5.3 - * - * @deprecated Use {@link #DEFAULT_LIST_SEMANTICS} instead. The specification - * actually leaves this behavior undefined, saying that portable applications - * should not rely on any specific behavior for a {@link java.util.List} with - * no {@code @OrderColumn}. - */ - @Deprecated( since = "6.0" ) - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_LIST_COMPLIANCE = "hibernate.jpa.compliance.list"; - - /** - * JPA specifies that items occurring in {@link jakarta.persistence.OrderBy} - * lists must be references to entity attributes, whereas Hibernate, by default, - * allows more complex expressions. - *

- * If enabled, an exception is thrown for items which are not entity attribute - * references. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isJpaOrderByMappingComplianceEnabled() - * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaOrderByMappingCompliance(boolean) - * - * @since 6.0 - */ - String JPA_ORDER_BY_MAPPING_COMPLIANCE = "hibernate.jpa.compliance.orderby"; - - /** - * JPA specifies that an {@link IllegalStateException} must be thrown by - * {@link jakarta.persistence.EntityManager#close()} and - * {@link jakarta.persistence.EntityManagerFactory#close()} if the object has - * already been closed. By default, Hibernate treats any additional call to - * {@code close()} as a noop. - *

- * When enabled, this setting forces Hibernate to throw an exception if - * {@code close()} is called on an instance that was already closed. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isJpaClosedComplianceEnabled() - * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaClosedCompliance(boolean) - * - * @since 5.3 - */ - String JPA_CLOSED_COMPLIANCE = "hibernate.jpa.compliance.closed"; - - /** - * The JPA specification insists that an - * {@link jakarta.persistence.EntityNotFoundException} must be thrown whenever - * an uninitialized entity proxy with no corresponding row in the database is - * accessed. For most programs, this results in many completely unnecessary - * round trips to the database. - *

- * Traditionally, Hibernate does not initialize an entity proxy when its - * identifier attribute is accessed, since the identifier value is already - * known and held in the proxy instance. This behavior saves the round trip - * to the database. - *

- * When enabled, this setting forces Hibernate to initialize the entity proxy - * when its identifier is accessed. Clearly, this setting is not recommended. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isJpaProxyComplianceEnabled() - * - * @since 5.2.13 - */ - String JPA_PROXY_COMPLIANCE = "hibernate.jpa.compliance.proxy"; - - /** - * By default, Hibernate uses second-level cache invalidation for entities - * with {@linkplain jakarta.persistence.SecondaryTable secondary tables} - * in order to avoid the possibility of inconsistent cached data in the - * case where different transactions simultaneously update different table - * rows corresponding to the same entity instance. - *

- * The JPA TCK, for no good reason, requires that entities with secondary - * tables be immediately cached in the second-level cache rather than - * invalidated and re-cached on a subsequent read. - *

- * Note that Hibernate's default behavior here is safer and more careful - * than the behavior mandated by the TCK but YOLO. - *

- * When enabled, this setting makes Hibernate pass the TCK. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isJpaCacheComplianceEnabled() - * @see org.hibernate.persister.entity.AbstractEntityPersister#isCacheInvalidationRequired() - * - * @since 5.3 - */ - String JPA_CACHING_COMPLIANCE = "hibernate.jpa.compliance.caching"; - - /** - * Determines whether the scope of any identifier generator name specified - * via {@link jakarta.persistence.TableGenerator#name()} or - * {@link jakarta.persistence.SequenceGenerator#name()} is considered global - * to the persistence unit, or local to the entity in which identifier generator - * is defined. - *

- * If enabled, the name will be considered globally scoped, and so the existence - * of two different generators with the same name will be considered a collision, - * and will result in an exception during bootstrap. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isGlobalGeneratorScopeEnabled() - * - * @since 5.2.17 - */ - String JPA_ID_GENERATOR_GLOBAL_SCOPE_COMPLIANCE = "hibernate.jpa.compliance.global_id_generators"; - - /** - * Determines if an identifier value passed to - * {@link jakarta.persistence.EntityManager#find} or - * {@link jakarta.persistence.EntityManager#getReference} may be - * {@linkplain org.hibernate.type.descriptor.java.JavaType#coerce coerced} to - * the identifier type declared by the entity. For example, an {@link Integer} - * argument might be widened to {@link Long}. - *

- * By default, coercion is allowed. When enabled, coercion is disallowed, as - * required by the JPA specification. - * - * @see org.hibernate.jpa.spi.JpaCompliance#isLoadByIdComplianceEnabled() - * - * @since 6.0 - */ - String JPA_LOAD_BY_ID_COMPLIANCE = "hibernate.jpa.compliance.load_by_id"; - - /** - * Determines if the identifier value stored in the database table backing a - * {@linkplain jakarta.persistence.TableGenerator table generator} is the last - * value returned by the identifier generator, or the next value to be returned. - *

- * By default, the value stored in the database table is the last generated value. - * - * @since 5.3 - */ - String TABLE_GENERATOR_STORE_LAST_USED = "hibernate.id.generator.stored_last_used"; - - /** - * When {@linkplain org.hibernate.query.Query#setMaxResults(int) pagination} is used - * in combination with a {@code fetch join} applied to a collection or many-valued - * association, the limit must be applied in-memory instead of on the database. This - * typically has terrible performance characteristics, and should be avoided. - *

- * When enabled, this setting specifies that an exception should be thrown for any - * query which would result in the limit being applied in-memory. - *

- * By default, the exception is disabled, and the possibility of terrible - * performance is left as a problem for the client to avoid. - * - * @since 5.2.13 - */ - String FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH = "hibernate.query.fail_on_pagination_over_collection_fetch"; - - /** - * This setting defines how {@link org.hibernate.annotations.Immutable} entities - * are handled when executing a bulk update query. Valid options are enumerated - * by {@link org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode}: - *

    - *
  • {@link org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode#WARNING "warning"} - * specifies that a warning log message is issued when an - * {@linkplain org.hibernate.annotations.Immutable immutable} entity is to be - * updated via a bulk update statement, and - *
  • {@link org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode#EXCEPTION "exception"} - * specifies that a {@link org.hibernate.HibernateException} should be thrown. - *
- *

- * By default, a warning is logged. - * - * @since 5.2.17 - * - * @see org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode - */ - String IMMUTABLE_ENTITY_UPDATE_QUERY_HANDLING_MODE = "hibernate.query.immutable_entity_update_query_handling_mode"; - - /** - * Determines how parameters occurring in a SQL {@code IN} predicate are expanded. - * By default, the {@code IN} predicate expands to include sufficient bind parameters - * to accommodate the specified arguments. - *

- * However, for database systems supporting execution plan caching, there's a - * better chance of hitting the cache if the number of possible {@code IN} clause - * parameter list lengths is smaller. - *

- * When this setting is enabled, we expand the number of bind parameters to an - * integer power of two: 4, 8, 16, 32, 64. Thus, if 5, 6, or 7 arguments are bound - * to a parameter, a SQL statement with 8 bind parameters in the {@code IN} clause - * will be used, and null will be bound to the left-over parameters. - * - * @since 5.2.17 - */ - String IN_CLAUSE_PARAMETER_PADDING = "hibernate.query.in_clause_parameter_padding"; - - /** - * This setting controls the number of {@link org.hibernate.stat.QueryStatistics} - * entries that will be stored by the Hibernate {@link org.hibernate.stat.Statistics} - * object. - *

- * The default value is {@value org.hibernate.stat.Statistics#DEFAULT_QUERY_STATISTICS_MAX_SIZE}. - * - * @since 5.4 - * - * @see org.hibernate.stat.Statistics#getQueries() - */ - String QUERY_STATISTICS_MAX_SIZE = "hibernate.statistics.query_max_size"; - - /** - * This setting defines the {@link org.hibernate.id.SequenceMismatchStrategy} used - * when Hibernate detects a mismatch between a sequence configuration in an entity - * mapping and its database sequence object counterpart. - *

- * Possible values are {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION}, - * {@link org.hibernate.id.SequenceMismatchStrategy#LOG}, - * {@link org.hibernate.id.SequenceMismatchStrategy#FIX} - * and {@link org.hibernate.id.SequenceMismatchStrategy#NONE}. - *

- * The default value is {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION}, - * meaning that an exception is thrown when such a conflict is detected. - * - * @since 5.4 - */ - String SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY = "hibernate.id.sequence.increment_size_mismatch_strategy"; - - /** - * Specifies the preferred JDBC type for storing boolean values. When no - * type is explicitly specified, a sensible - * {@link org.hibernate.dialect.Dialect#getPreferredSqlTypeCodeForBoolean() - * dialect-specific default type code} is used. - *

- * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, - * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. - *

- * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant - * field, for example, {@code hibernate.type.preferred_boolean_jdbc_type=BIT}. - * - * @since 6.0 - */ - @Incubating - String PREFERRED_BOOLEAN_JDBC_TYPE = "hibernate.type.preferred_boolean_jdbc_type"; - - /** - * The preferred JDBC type to use for storing {@link java.util.UUID} values. - * Defaults to {@link org.hibernate.type.SqlTypes#UUID}. - *

- * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, - * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. - *

- * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant - * field, for example, {@code hibernate.type.preferred_uuid_jdbc_type=CHAR}. - * - * @since 6.0 - */ - @Incubating - String PREFERRED_UUID_JDBC_TYPE = "hibernate.type.preferred_uuid_jdbc_type"; - - /** - * The preferred JDBC type to use for storing {@link java.time.Duration} values. - * Defaults to {@link org.hibernate.type.SqlTypes#NUMERIC}. - *

- * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, - * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. - *

- * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant - * field, for example, {@code hibernate.type.preferred_duration_jdbc_type=INTERVAL_SECOND}. - * - * @since 6.0 - */ - @Incubating - String PREFERRED_DURATION_JDBC_TYPE = "hibernate.type.preferred_duration_jdbc_type"; - - /** - * Specifies the preferred JDBC type for storing {@link java.time.Instant} values. - * Defaults to {@link org.hibernate.type.SqlTypes#TIMESTAMP_UTC}. - * is used. - *

- * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, - * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. - *

- * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant - * field, for example, {@code hibernate.type.preferred_instant_jdbc_type=TIMESTAMP}. - * - * @since 6.0 - */ - @Incubating - String PREFERRED_INSTANT_JDBC_TYPE = "hibernate.type.preferred_instant_jdbc_type"; - - /** - * Specifies a {@link org.hibernate.type.format.FormatMapper} used for JSON - * serialization and deserialization, either: - *

    - *
  • an instance of {@code FormatMapper}, - *
  • a {@link Class} representing a class that implements {@code FormatMapper}, - *
  • the name of a class that implements {@code FormatMapper}, or - *
  • one of the shorthand constants {@code jackson} or {@code jsonb}. - *
- *

- * By default, the first of the possible providers that is available at runtime is - * used, according to the listing order. - * - * @since 6.0 - * @see org.hibernate.boot.SessionFactoryBuilder#applyJsonFormatMapper(FormatMapper) - */ - @Incubating - String JSON_FORMAT_MAPPER = "hibernate.type.json_format_mapper"; - - /** - * Specifies a {@link org.hibernate.type.format.FormatMapper} used for XML - * serialization and deserialization, either: - *

    - *
  • an instance of {@code FormatMapper}, - *
  • a {@link Class} representing a class that implements {@code FormatMapper}, - *
  • the name of a class that implements {@code FormatMapper}, or - *
  • one of the shorthand constants {@code jackson} or {@code jaxb}. - *
- *

- * By default, the first of the possible providers that is available at runtime is - * used, according to the listing order. - * - * @since 6.0.1 - * @see org.hibernate.boot.SessionFactoryBuilder#applyXmlFormatMapper(FormatMapper) - */ - @Incubating - String XML_FORMAT_MAPPER = "hibernate.type.xml_format_mapper"; - - /** - * Configurable control over how to handle {@code Byte[]} and {@code Character[]} types - * encountered in the application domain model. Allowable semantics are defined by - * {@link WrapperArrayHandling}. Accepted values include:

    - *
  1. {@link WrapperArrayHandling} instance
  2. - *
  3. case-insensitive name of a {@link WrapperArrayHandling} instance (e.g. {@code allow})
  4. - *
- * - * @since 6.2 - */ - @Incubating - String WRAPPER_ARRAY_HANDLING = "hibernate.type.wrapper_array_handling"; - - /** - * Specifies the default strategy for storage of the timezone information for the zoned - * datetime types {@link java.time.OffsetDateTime} and {@link java.time.ZonedDateTime}. - * The possible options for this setting are enumerated by - * {@link org.hibernate.annotations.TimeZoneStorageType}. - *

- * The default is {@link org.hibernate.annotations.TimeZoneStorageType#DEFAULT DEFAULT}, - * which guarantees that the {@linkplain java.time.OffsetDateTime#toInstant() instant} - * represented by a zoned datetime type is preserved by a round trip to the database. - * It does not guarantee that the time zone or offset is preserved. - *

- * For backward compatibility with older versions of Hibernate, set this property to - * {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE NORMALIZE}. - *

- * The default strategy specified using this setting may be overridden using the - * annotation {@link org.hibernate.annotations.TimeZoneStorage}. - * - * @see org.hibernate.annotations.TimeZoneStorageType - * @see org.hibernate.annotations.TimeZoneStorage - * - * @since 6.0 - */ - String TIMEZONE_DEFAULT_STORAGE = "hibernate.timezone.default_storage"; - - /** - * Controls whether to use JDBC markers (`?`) or dialect native markers for parameters - * within {@linkplain java.sql.PreparedStatement preparable} SQL statements. - * - * @implNote {@code False} by default, indicating standard JDBC parameter markers (`?`) - * are used. Set to {@code true} to use the Dialect's native markers, if any. For - * Dialects without native markers, the standard JDBC strategy is used. - * - * @see ParameterMarkerStrategy - * @see org.hibernate.dialect.Dialect#getNativeParameterMarkerStrategy() - * - * @since 6.2 - */ - @Incubating - String DIALECT_NATIVE_PARAM_MARKERS = "hibernate.dialect.native_param_markers"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Java (javax) Persistence defined settings - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - /** - * Specifies a class implementing {@link jakarta.persistence.spi.PersistenceProvider}. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.4 - * - * @deprecated Use {@link #JAKARTA_PERSISTENCE_PROVIDER} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_PERSISTENCE_PROVIDER = "javax.persistence.provider"; - - /** - * The type of transactions supported by the entity managers. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.2 - * - * @deprecated Use {@link #JAKARTA_TRANSACTION_TYPE} instead - */ - @Deprecated - String JPA_TRANSACTION_TYPE = "javax.persistence.transactionType"; - - /** - * The JNDI name of a JTA {@link javax.sql.DataSource}. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.5 - * - * @deprecated Use {@link #JAKARTA_JTA_DATASOURCE} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_JTA_DATASOURCE = "javax.persistence.jtaDataSource"; - - /** - * The JNDI name of a non-JTA {@link javax.sql.DataSource}. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.5 - * - * @deprecated Use {@link #JAKARTA_NON_JTA_DATASOURCE} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_NON_JTA_DATASOURCE = "javax.persistence.nonJtaDataSource"; - - /** - * The name of a JDBC driver to use to connect to the database. - *

- * Used in conjunction with {@link #JPA_JDBC_URL}, {@link #JPA_JDBC_USER} and - * {@link #JPA_JDBC_PASSWORD} to specify how to connect to the database. - *

- * When connections are obtained from a {@link javax.sql.DataSource}, use either - * {@link #JPA_JTA_DATASOURCE} or {@link #JPA_NON_JTA_DATASOURCE} instead. - *

- * See section 8.2.1.9 - * - * @deprecated Use {@link #JAKARTA_JDBC_DRIVER} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_JDBC_DRIVER = "javax.persistence.jdbc.driver"; - - /** - * The JDBC connection URL to use to connect to the database. - *

- * Used in conjunction with {@link #JPA_JDBC_DRIVER}, {@link #JPA_JDBC_USER} and - * {@link #JPA_JDBC_PASSWORD} to specify how to connect to the database. - *

- * When connections are obtained from a {@link javax.sql.DataSource}, use either - * {@link #JPA_JTA_DATASOURCE} or {@link #JPA_NON_JTA_DATASOURCE} instead. - *

- * See section 8.2.1.9 - * - * @deprecated Use {@link #JAKARTA_JDBC_URL} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_JDBC_URL = "javax.persistence.jdbc.url"; - - /** - * The database user to use when connecting via JDBC. - *

- * Used in conjunction with {@link #JPA_JDBC_DRIVER}, {@link #JPA_JDBC_URL} and - * {@link #JPA_JDBC_PASSWORD} to specify how to connect to the database. - *

- * See section 8.2.1.9 - * - * @deprecated Use {@link #JAKARTA_JDBC_USER} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_JDBC_USER = "javax.persistence.jdbc.user"; - - /** - * The password to use when connecting via JDBC. - *

- * Used in conjunction with {@link #JPA_JDBC_DRIVER}, {@link #JPA_JDBC_URL} and - * {@link #JPA_JDBC_USER} to specify how to connect to the database. - *

- * See JPA 2 section 8.2.1.9 - * - * @deprecated Use {@link #JAKARTA_JDBC_PASSWORD} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_JDBC_PASSWORD = "javax.persistence.jdbc.password"; - - /** - * Used to indicate whether second-level (what JPA terms shared cache) - * caching is enabled as per the rules defined in JPA 2 section 3.1.7. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.7 - * @see jakarta.persistence.SharedCacheMode - * - * @deprecated Use {@link #JAKARTA_SHARED_CACHE_MODE} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_SHARED_CACHE_MODE = "javax.persistence.sharedCache.mode"; - - /** - * Used to indicate if the provider should attempt to retrieve requested - * data in the shared cache. - * - * @see jakarta.persistence.CacheRetrieveMode - * - * @deprecated Use {@link #JAKARTA_SHARED_CACHE_RETRIEVE_MODE} instead - * - * @apiNote This is not a legal property for an {@code EntityManagerFactory}. - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_SHARED_CACHE_RETRIEVE_MODE = "javax.persistence.cache.retrieveMode"; - - /** - * Used to indicate if the provider should attempt to store data loaded from the database - * in the shared cache. - * - * @see jakarta.persistence.CacheStoreMode - * - * @deprecated Use {@link #JAKARTA_SHARED_CACHE_STORE_MODE} instead - * - * @apiNote This is not a legal property for an {@code EntityManagerFactory}. - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_SHARED_CACHE_STORE_MODE = "javax.persistence.cache.storeMode"; - - /** - * Used to indicate what form of automatic validation is in effect as - * per rules defined in JPA 2 section 3.6.1.1. - *

- * See JPA 2 sections 9.4.3 and 8.2.1.8 - * - * @see jakarta.persistence.ValidationMode - * - * @deprecated Use {@link #JAKARTA_VALIDATION_MODE} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_VALIDATION_MODE = "javax.persistence.validation.mode"; - - /** - * Used to pass along any discovered validator factory. - * - * @deprecated Use {@link #JAKARTA_VALIDATION_FACTORY} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_VALIDATION_FACTORY = "javax.persistence.validation.factory"; - - /** - * Used to coordinate with bean validators. - *

- * See JPA 2 section 8.2.1.9 - * - * @deprecated Use {@link #JAKARTA_PERSIST_VALIDATION_GROUP} instead - */ - @Deprecated - String JPA_PERSIST_VALIDATION_GROUP = "javax.persistence.validation.group.pre-persist"; - - /** - * Used to coordinate with bean validators. - *

- * See JPA 2 section 8.2.1.9 - * - * @deprecated Use {@link #JAKARTA_UPDATE_VALIDATION_GROUP} instead - */ - @Deprecated - String JPA_UPDATE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-update"; - - /** - * Used to coordinate with bean validators. - *

- * See JPA 2 section 8.2.1.9 - * - * @deprecated Use {@link #JAKARTA_REMOVE_VALIDATION_GROUP} instead - */ - @Deprecated - String JPA_REMOVE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-remove"; - - /** - * Used to request (hint) a pessimistic lock scope. - *

- * See JPA 2 sections 8.2.1.9 and 3.4.4.3 - * - * @deprecated Use {@link #JAKARTA_LOCK_SCOPE} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_LOCK_SCOPE = LegacySpecHints.HINT_JAVAEE_LOCK_SCOPE; - - /** - * Used to request (hint) a pessimistic lock timeout (in milliseconds). - *

- * See JPA 2 sections 8.2.1.9 and 3.4.4.3 - * - * @deprecated Use {@link #JAKARTA_LOCK_TIMEOUT} instead - */ - @Deprecated - @SuppressWarnings("DeprecatedIsStillUsed") - String JPA_LOCK_TIMEOUT = LegacySpecHints.HINT_JAVAEE_LOCK_TIMEOUT; - - /** - * Used to pass a CDI {@link jakarta.enterprise.inject.spi.BeanManager} to - * Hibernate. - *

- * According to the JPA specification, the {@code BeanManager} should be - * passed at boot time and be ready for immediate use at that time. But - * not all environments can do this (WildFly, for example). To accommodate - * such environments, Hibernate provides two options: - *

    - *
  1. A proprietary CDI extension SPI (which has been proposed to the CDI - * spec group as a standard option) which can be used to provide delayed - * {@code BeanManager} access: to use this solution, the reference passed - * as the {@code BeanManager} during bootstrap should be typed as - * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager}. - *
  2. Delayed access to the {@code BeanManager} reference: here, Hibernate - * will not access the reference passed as the {@code BeanManager} during - * bootstrap until it is first needed. Note, however, that this has the - * effect of delaying the detection of any deployment problems until after - * bootstrapping. - *
- * This setting is used to configure access to the {@code BeanManager}, - * either directly, or via - * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager}. - * - * @deprecated Use {@link #JAKARTA_CDI_BEAN_MANAGER} instead - */ - @Deprecated - String CDI_BEAN_MANAGER = "javax.persistence.bean.manager"; - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // pulled from jpa.AvailableSettings - - /** - * Used to determine flush mode. - * * @deprecated There are much better ways to control the flush mode of a session, * for example, {@link org.hibernate.SessionBuilder#flushMode} or * {@link org.hibernate.Session#setHibernateFlushMode}. @@ -3154,67 +212,6 @@ public interface AvailableSettings { @SuppressWarnings("DeprecatedIsStillUsed") String FLUSH_MODE = "org.hibernate.flushMode"; - String CFG_XML_FILE = "hibernate.cfg_xml_file"; - String ORM_XML_FILES = "hibernate.orm_xml_files"; - String HBM_XML_FILES = "hibernate.hbm_xml_files"; - String LOADED_CLASSES = "hibernate.loaded_classes"; - - /** - * Event listener configuration properties follow the pattern - * {@code hibernate.event.listener.eventType packageName.ClassName1, packageName.ClassName2} - */ - String EVENT_LISTENER_PREFIX = "hibernate.event.listener"; - - /** - * Entity cache configuration properties follow the pattern - * {@code hibernate.classcache.packagename.ClassName usage[, region]} - * where {@code usage} is the cache strategy used and {@code region} the cache region name - */ - String CLASS_CACHE_PREFIX = "hibernate.classcache"; - - /** - * Collection cache configuration properties follow the pattern - * {@code hibernate.collectioncache.packagename.ClassName.role usage[, region]} - * where {@code usage} is the cache strategy used and {@code region} the cache region name - */ - String COLLECTION_CACHE_PREFIX = "hibernate.collectioncache"; - - /** - * Enable dirty tracking feature in runtime bytecode enhancement - * - * @deprecated Will be removed without replacement. See HHH-15641 - */ - @Deprecated(forRemoval = true) - @SuppressWarnings("DeprecatedIsStillUsed") - String ENHANCER_ENABLE_DIRTY_TRACKING = "hibernate.enhancer.enableDirtyTracking"; - - /** - * Enable lazy loading feature in runtime bytecode enhancement - * - * @deprecated Will be removed without replacement. See HHH-15641 - */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated(forRemoval = true) - String ENHANCER_ENABLE_LAZY_INITIALIZATION = "hibernate.enhancer.enableLazyInitialization"; - - /** - * Enable association management feature in runtime bytecode enhancement - */ - String ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT = "hibernate.enhancer.enableAssociationManagement"; - - /** - * Specifies the name of the persistence unit. - */ - String PERSISTENCE_UNIT_NAME = "hibernate.persistenceUnitName"; - - /** - * Specifies a class which implements {@link org.hibernate.SessionFactoryObserver} and has - * a constructor with no parameters. - * - * @see org.hibernate.boot.SessionFactoryBuilder#addSessionFactoryObservers(SessionFactoryObserver...) - */ - String SESSION_FACTORY_OBSERVER = "hibernate.session_factory_observer"; - /** * Specifies a class which implements {@link org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider}, * and has a constructor with no parameters. @@ -3224,67 +221,4 @@ public interface AvailableSettings { @Deprecated(since = "6.0") @SuppressWarnings("DeprecatedIsStillUsed") String IDENTIFIER_GENERATOR_STRATEGY_PROVIDER = "hibernate.identifier_generator_strategy_provider"; - - /** - * When enabled, specifies that the persistent context should be discarded when either - * {@link org.hibernate.Session#close()} or {@link jakarta.persistence.EntityManager#close()} - * is called. - *

- * By default, the persistent context is not discarded, as per the JPA specification. - */ - String DISCARD_PC_ON_CLOSE = "hibernate.discard_pc_on_close"; - - /** - * Whether XML should be validated against their schema as Hibernate reads them. - *

- * Default is {@code true} - * - * @since 6.1 - */ - String VALIDATE_XML = "hibernate.validate_xml"; - - /** - * Enables processing {@code hbm.xml} mappings by transforming them to {@code mapping.xml} and using - * that processor. Default is false, must be opted-into. - * - * @since 6.1 - */ - String TRANSFORM_HBM_XML = "hibernate.transform_hbm_xml.enabled"; - - /** - * How features in a {@code hbm.xml} file which are not supported for transformation should be handled. - *

- * Default is {@link org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling#ERROR} - * - * @see org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling - * @since 6.1 - */ - String TRANSFORM_HBM_XML_FEATURE_HANDLING = "hibernate.transform_hbm_xml.unsupported_feature_handling"; - - /** - * Allows creation of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#PERSISTENT persistent} - * temporary tables at application startup to be disabled. By default, table creation is enabled. - */ - String BULK_ID_STRATEGY_PERSISTENT_TEMPORARY_CREATE_TABLES = PersistentTableStrategy.CREATE_ID_TABLES; - /** - * Allows dropping of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#PERSISTENT persistent} - * temporary tables at application shutdown to be disabled. By default, table dropping is enabled. - */ - String BULK_ID_STRATEGY_PERSISTENT_TEMPORARY_DROP_TABLES = PersistentTableStrategy.DROP_ID_TABLES; - /** - * Allows creation of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#GLOBAL global} - * temporary tables at application startup to be disabled. By default, table creation is enabled. - */ - String BULK_ID_STRATEGY_GLOBAL_TEMPORARY_CREATE_TABLES = GlobalTemporaryTableStrategy.CREATE_ID_TABLES; - /** - * Allows dropping of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#GLOBAL global} - * temporary tables at application shutdown to be disabled. By default, table dropping is enabled. - */ - String BULK_ID_STRATEGY_GLOBAL_TEMPORARY_DROP_TABLES = GlobalTemporaryTableStrategy.DROP_ID_TABLES; - /** - * Allows dropping of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#LOCAL local} - * temporary tables at transaction commit to be enabled. By default, table dropping is disabled, - * and the database will drop the temporary tables automatically. - */ - String BULK_ID_STRATEGY_LOCAL_TEMPORARY_DROP_TABLES = LocalTemporaryTableStrategy.DROP_ID_TABLES; } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/BatchSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/BatchSettings.java new file mode 100644 index 0000000000..b46922803c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/BatchSettings.java @@ -0,0 +1,73 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import java.sql.PreparedStatement; + +import org.hibernate.engine.jdbc.batch.spi.BatchBuilder; + +/** + * @author Steve Ebersole + */ +public interface BatchSettings { + /** + * Names the {@link BatchBuilder} implementation to use. + * + * @settingDefault Standard builder based on {@link #STATEMENT_BATCH_SIZE} + */ + String BUILDER = "hibernate.jdbc.batch.builder"; + + /** + * Specifies the maximum number of {@linkplain java.sql.PreparedStatement statements} + * to {@linkplain PreparedStatement#addBatch batch} together. + *

+ * A nonzero value enables batching + * + * @see java.sql.PreparedStatement#executeBatch + * @see java.sql.PreparedStatement#addBatch + * @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchSize + * + * @settingDefault 0 + */ + String STATEMENT_BATCH_SIZE = "hibernate.jdbc.batch_size"; + + /** + * Enable ordering of update statements by primary key value, for the purpose of more + * efficient JDBC batching + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyOrderingOfUpdates + * + * @settingDefault {@code false} + */ + String ORDER_UPDATES = "hibernate.order_updates"; + + /** + * Enable ordering of insert statements by primary key value, for the purpose of more + * efficient JDBC batching. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyOrderingOfInserts + * + * @settingDefault {@code false} + */ + String ORDER_INSERTS = "hibernate.order_inserts"; + + /** + * When enabled, specifies that {@linkplain jakarta.persistence.Version versioned} + * data should be included in batching. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchingForVersionedEntities(boolean) + * + * @settingDefault Generally {@code true}, though can vary based on Dialect + */ + String BATCH_VERSIONED_DATA = "hibernate.jdbc.batch_versioned_data"; + + /** + * @deprecated Use {@link #BUILDER} instead + */ + @Deprecated + String BATCH_STRATEGY = "hibernate.jdbc.factory_class"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/BytecodeSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/BytecodeSettings.java new file mode 100644 index 0000000000..1f1b4efdcb --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/BytecodeSettings.java @@ -0,0 +1,46 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +/** + * Settings which control the {@link org.hibernate.bytecode.spi.BytecodeProvider} + * used for bytecode enhancement and reflection optimization. + * + * @author Steve Ebersole + */ +public interface BytecodeSettings { + + /** + * Selects a bytecode enhancement library. + *

+ * At present only bytebuddy is supported, bytebuddy being the default since version 5.3. + * + * @settingDefault {@code "bytebuddy"} + */ + String BYTECODE_PROVIDER = "hibernate.bytecode.provider"; + + /** + * Enable association management feature in runtime bytecode enhancement + * + * @settingDefault {@code false} + */ + String ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT = "hibernate.enhancer.enableAssociationManagement"; + + /** + * @deprecated Will be removed without replacement. See HHH-15641 + */ + @Deprecated(forRemoval = true) + @SuppressWarnings("DeprecatedIsStillUsed") + String ENHANCER_ENABLE_DIRTY_TRACKING = "hibernate.enhancer.enableDirtyTracking"; + + /** + * @deprecated Will be removed without replacement. See HHH-15641 + */ + @SuppressWarnings("DeprecatedIsStillUsed") + @Deprecated(forRemoval = true) + String ENHANCER_ENABLE_LAZY_INITIALIZATION = "hibernate.enhancer.enableLazyInitialization"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/C3p0Settings.java b/hibernate-core/src/main/java/org/hibernate/cfg/C3p0Settings.java new file mode 100644 index 0000000000..7d6f5f3887 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/C3p0Settings.java @@ -0,0 +1,48 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +/** + * @author Steve Ebersole + */ +public interface C3p0Settings { + + /** + * A setting prefix used to indicate settings that target the hibernate-c3p0 integration + */ + String C3P0_CONFIG_PREFIX = "hibernate.c3p0"; + + /** + * Maximum size of C3P0 connection pool + */ + String C3P0_MAX_SIZE = "hibernate.c3p0.max_size"; + + /** + * Minimum size of C3P0 connection pool + */ + String C3P0_MIN_SIZE = "hibernate.c3p0.min_size"; + + /** + * Maximum idle time for C3P0 connection pool + */ + String C3P0_TIMEOUT = "hibernate.c3p0.timeout"; + + /** + * Maximum size of C3P0 statement cache + */ + String C3P0_MAX_STATEMENTS = "hibernate.c3p0.max_statements"; + + /** + * Number of connections acquired when pool is exhausted + */ + String C3P0_ACQUIRE_INCREMENT = "hibernate.c3p0.acquire_increment"; + + /** + * Idle time before a C3P0 pooled connection is validated + */ + String C3P0_IDLE_TEST_PERIOD = "hibernate.c3p0.idle_test_period"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/CacheSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/CacheSettings.java new file mode 100644 index 0000000000..ca8c3fea55 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/CacheSettings.java @@ -0,0 +1,241 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.cache.internal.NoCachingRegionFactory; +import org.hibernate.cache.spi.RegionFactory; +import org.hibernate.cache.spi.TimestampsCacheFactory; +import org.hibernate.jpa.SpecHints; + +/** + * Settings for Hibernate's second-level caching + * + * @author Steve Ebersole + */ +public interface CacheSettings { + /** + * When enabled, specifies that the second-level cache (which JPA calls the + * "shared" cache) may be used, as per the rules defined in JPA 2 section 3.1.7. + *

+ * See JPA 2 sections 9.4.3 and 8.2.1.7 + * + * @see jakarta.persistence.SharedCacheMode + */ + String JAKARTA_SHARED_CACHE_MODE = "jakarta.persistence.sharedCache.mode"; + + /** + * Set a default value for {@link SpecHints#HINT_SPEC_CACHE_RETRIEVE_MODE}, + * used when the hint is not explicitly specified. + *

+ * It does not usually make sense to change the default from + * {@link jakarta.persistence.CacheRetrieveMode#USE}. + * + * @see SpecHints#HINT_SPEC_CACHE_RETRIEVE_MODE + */ + String JAKARTA_SHARED_CACHE_RETRIEVE_MODE = SpecHints.HINT_SPEC_CACHE_RETRIEVE_MODE; + + /** + * Set a default value for {@link SpecHints#HINT_SPEC_CACHE_STORE_MODE}, + * used when the hint is not explicitly specified. + *

+ * It does not usually make sense to change the default from + * {@link jakarta.persistence.CacheStoreMode#USE}. + * + * @see SpecHints#HINT_SPEC_CACHE_RETRIEVE_MODE + */ + String JAKARTA_SHARED_CACHE_STORE_MODE = SpecHints.HINT_SPEC_CACHE_STORE_MODE; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Hibernate settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * When enabled, specifies that the second-level cache may be used. + *

+ * By default, if the configured {@link RegionFactory} + * is not the {@link org.hibernate.cache.internal.NoCachingRegionFactory}, then + * the second-level cache is enabled. Otherwise, the second-level cache is disabled. + * + * @settingDefault {@code true} when a {@linkplain #CACHE_REGION_FACTORY provider} is + * specified; {@code false} otherwise. + * + * @see #CACHE_REGION_FACTORY + * @see org.hibernate.boot.SessionFactoryBuilder#applySecondLevelCacheSupport(boolean) + */ + String USE_SECOND_LEVEL_CACHE = "hibernate.cache.use_second_level_cache"; + + /** + * Enable the query results cache + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyQueryCacheSupport(boolean) + */ + String USE_QUERY_CACHE = "hibernate.cache.use_query_cache"; + + /** + * The {@link RegionFactory} implementation, either: + *

    + *
  • an instance of {@link RegionFactory}, + *
  • a {@link Class} implementing {@link RegionFactory}, or + *
  • he name of a class implementing {@link RegionFactory}. + *
+ *

+ * Defaults to {@link NoCachingRegionFactory}, so that caching is disabled. + * + * @see #USE_SECOND_LEVEL_CACHE + */ + String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class"; + + /** + * Specifies the {@link org.hibernate.cache.spi.TimestampsCacheFactory} to use. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyTimestampsCacheFactory(TimestampsCacheFactory) + */ + String QUERY_CACHE_FACTORY = "hibernate.cache.query_cache_factory"; + + /** + * The {@code CacheProvider} region name prefix + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyCacheRegionPrefix(String) + */ + String CACHE_REGION_PREFIX = "hibernate.cache.region_prefix"; + + /** + * Specifies the {@link org.hibernate.annotations.CacheConcurrencyStrategy} to use by + * default when an entity is marked {@link jakarta.persistence.Cacheable @Cacheable}, + * but no concurrency strategy is explicitly specified via the + * {@link org.hibernate.annotations.Cache} annotation. + *

+ * An explicit strategy may be specified using + * {@link org.hibernate.annotations.Cache#usage @Cache(usage=...)}. + * + * @settingDefault The cache provider's default strategy + * + * @see org.hibernate.boot.MetadataBuilder#applyAccessType(org.hibernate.cache.spi.access.AccessType) + * @see RegionFactory#getDefaultAccessType + */ + String DEFAULT_CACHE_CONCURRENCY_STRATEGY = "hibernate.cache.default_cache_concurrency_strategy"; + + /** + * Optimize interaction with the second-level cache to minimize writes, at the cost + * of an additional read before each write. This setting is useful if writes to the + * cache are much more expensive than reads from the cache, for example, if the cache + * is a distributed cache. + *

+ * It's not usually necessary to set this explicitly because, by default, it's set + * to a {@linkplain org.hibernate.boot.SessionFactoryBuilder#applyMinimalPutsForCaching(boolean) + * sensible value} by the second-level cache implementation. + * + * @settingDefault The cache provider's default + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyMinimalPutsForCaching(boolean) + * @see RegionFactory#isMinimalPutsEnabledByDefault() + */ + String USE_MINIMAL_PUTS = "hibernate.cache.use_minimal_puts"; + + /** + * Enables the use of structured second-level cache entries. This makes the cache + * entries human-readable, but carries a performance cost. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyStructuredCacheEntries(boolean) + */ + String USE_STRUCTURED_CACHE = "hibernate.cache.use_structured_entries"; + + /** + * Enables the automatic eviction of a bidirectional association's collection + * cache when an element in the {@link jakarta.persistence.ManyToOne} collection + * is added, updated, or removed without properly managing the change on the + * {@link jakarta.persistence.OneToMany} side. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyAutomaticEvictionOfCollectionCaches(boolean) + */ + String AUTO_EVICT_COLLECTION_CACHE = "hibernate.cache.auto_evict_collection_cache"; + + /** + * Enable direct storage of entity references into the second level cache when + * applicable. This is appropriate only for immutable entities. + *

+ * By default, entities are always stored in a "disassembled" form, that is, as + * a tuple of attribute values. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyDirectReferenceCaching(boolean) + */ + String USE_DIRECT_REFERENCE_CACHE_ENTRIES = "hibernate.cache.use_reference_entries"; + + /** + * Specifies the {@link org.hibernate.cache.spi.CacheKeysFactory} to use, either: + *

    + *
  • an instance of {@link org.hibernate.cache.spi.CacheKeysFactory}, + *
  • a {@link Class} implementing {@link org.hibernate.cache.spi.CacheKeysFactory}, + *
  • the name of a class implementing {@link org.hibernate.cache.spi.CacheKeysFactory}, + *
  • {@code "default"} as a short name for {@link org.hibernate.cache.internal.DefaultCacheKeysFactory}, or + *
  • {@code "simple"} as a short name for {@link org.hibernate.cache.internal.SimpleCacheKeysFactory}. + *
+ * + * @since 5.2 + * + * @deprecated this is only honored for {@code hibernate-infinispan} + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String CACHE_KEYS_FACTORY = "hibernate.cache.keys_factory"; + + /** + * Entity cache configuration properties follow the pattern + * {@code hibernate.classcache.packagename.ClassName usage[, region]} + * where {@code usage} is the cache strategy used and {@code region} the cache region name + */ + String CLASS_CACHE_PREFIX = "hibernate.classcache"; + + /** + * Collection cache configuration properties follow the pattern + * {@code hibernate.collectioncache.packagename.ClassName.role usage[, region]} + * where {@code usage} is the cache strategy used and {@code region} the cache region name + */ + String COLLECTION_CACHE_PREFIX = "hibernate.collectioncache"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Legacy JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Used to indicate whether second-level (what JPA terms shared cache) + * caching is enabled as per the rules defined in JPA 2 section 3.1.7. + *

+ * See JPA 2 sections 9.4.3 and 8.2.1.7 + * @see jakarta.persistence.SharedCacheMode + * + * @deprecated Use {@link #JAKARTA_SHARED_CACHE_MODE} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_SHARED_CACHE_MODE = "javax.persistence.sharedCache.mode"; + + /** + * @deprecated Use {@link #JAKARTA_SHARED_CACHE_RETRIEVE_MODE} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_SHARED_CACHE_RETRIEVE_MODE = "javax.persistence.cache.retrieveMode"; + + /** + * @deprecated Use {@link #JAKARTA_SHARED_CACHE_STORE_MODE} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_SHARED_CACHE_STORE_MODE = "javax.persistence.cache.storeMode"; + +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/EnvironmentSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/EnvironmentSettings.java new file mode 100644 index 0000000000..4c60e0aade --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/EnvironmentSettings.java @@ -0,0 +1,56 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import java.util.Hashtable; +import javax.naming.InitialContext; + +/** + * @author Steve Ebersole + */ +public interface EnvironmentSettings { + /** + * Specifies the JNDI {@link javax.naming.spi.InitialContextFactory} implementation + * class to use. Passed along to {@link InitialContext#InitialContext(Hashtable)} + * as {@value javax.naming.Context#INITIAL_CONTEXT_FACTORY}. + * + * @see javax.naming.Context#INITIAL_CONTEXT_FACTORY + */ + String JNDI_CLASS = "hibernate.jndi.class"; + + /** + * Specifies the JNDI provider/connection URL. Passed along to + * {@link InitialContext#InitialContext(Hashtable)} as + * {@value javax.naming.Context#PROVIDER_URL}. + * + * @see javax.naming.Context#PROVIDER_URL + */ + String JNDI_URL = "hibernate.jndi.url"; + + /** + * A prefix for properties specifying arbitrary JNDI {@link javax.naming.InitialContext} + * properties. These properties are simply passed along to the constructor + * {@link javax.naming.InitialContext#InitialContext(java.util.Hashtable)}. + */ + String JNDI_PREFIX = "hibernate.jndi"; + + /** + * Specifies a {@link java.util.Collection collection} of the {@link ClassLoader} + * instances Hibernate should use for classloading and resource loading. + * + * @since 5.0 + */ + String CLASSLOADERS = "hibernate.classLoaders"; + + /** + * Specifies how the {@linkplain Thread#getContextClassLoader() thread context} + * {@linkplain ClassLoader class loader} must be used for class lookup. + * + * @see org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence + */ + String TC_CLASSLOADER = "hibernate.classLoader.tccl_lookup_precedence"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/FetchSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/FetchSettings.java new file mode 100644 index 0000000000..5555a3e24b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/FetchSettings.java @@ -0,0 +1,62 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.annotations.BatchSize; + +/** + * @author Steve Ebersole + */ +public interface FetchSettings { + /** + * Specifies the maximum depth of nested outer join fetching. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyMaximumFetchDepth + * + * @settingDefault 0 (none) + */ + String MAX_FETCH_DEPTH = "hibernate.max_fetch_depth"; + + /** + * Specifies the default value for {@linkplain BatchSize#size() batch fetching}. + *

+ * By default, Hibernate only uses batch fetching for entities and collections explicitly + * annotated {@code @BatchSize}. + * + * @see org.hibernate.annotations.BatchSize + * @see org.hibernate.Session#setFetchBatchSize(int) + * @see org.hibernate.boot.SessionFactoryBuilder#applyDefaultBatchFetchSize(int) + */ + String DEFAULT_BATCH_FETCH_SIZE = "hibernate.default_batch_fetch_size"; + + /** + * When enabled, Hibernate will use subselect fetching, when possible, to + * fetch any collection. Subselect fetching involves fetching the collection + * based on the restriction used to load it owner(s). + *

+ * By default, Hibernate only uses subselect fetching for collections + * explicitly annotated {@linkplain org.hibernate.annotations.FetchMode#SUBSELECT @Fetch(SUBSELECT)}. + * + * @since 6.3 + * + * @see org.hibernate.annotations.FetchMode#SUBSELECT + * @see org.hibernate.Session#setSubselectFetchingEnabled(boolean) + * @see org.hibernate.boot.SessionFactoryBuilder#applySubselectFetchEnabled(boolean) + */ + String USE_SUBSELECT_FETCH = "hibernate.use_subselect_fetch"; + + /** + * Specifies the {@link org.hibernate.loader.BatchFetchStyle} to use, + * either the name of a {code BatchFetchStyle} instance, or an instance + * of {@code BatchFetchStyle}. + * + * @deprecated An appropriate batch-fetch style is selected automatically + */ + @Deprecated(since = "6.0") + @SuppressWarnings("DeprecatedIsStillUsed") + String BATCH_FETCH_STYLE = "hibernate.batch_fetch_style"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java new file mode 100644 index 0000000000..e25dd49d74 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java @@ -0,0 +1,611 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import java.util.Calendar; + +import org.hibernate.Incubating; +import org.hibernate.context.spi.CurrentTenantIdentifierResolver; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData; +import org.hibernate.query.Query; +import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; +import org.hibernate.resource.jdbc.spi.StatementInspector; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; + +/** + * Settings related to JDBC, Connections, pools, Dialects, etc + * + * @author Steve Ebersole + */ +public interface JdbcSettings extends C3p0Settings, ProxoolSettings { + + /** + * Specifies a JTA {@link javax.sql.DataSource} to use for Connections. + * Hibernate allows either + *

    + *
  • + * an instance of {@link javax.sql.DataSource} + *
  • + *
  • + * a JNDI name under which to obtain the {@link javax.sql.DataSource}; + * see also {@link EnvironmentSettings#JNDI_URL}, {@link EnvironmentSettings#JNDI_CLASS}, + * {@link EnvironmentSettings#JNDI_PREFIX} + *
  • + *
+ *

+ * See JPA 2 sections 9.4.3 and 8.2.1.5 + */ + String JAKARTA_JTA_DATASOURCE = "jakarta.persistence.jtaDataSource"; + + /** + * Specifies a non-JTA {@link javax.sql.DataSource} to use for Connections. + * Hibernate allows either + *

    + *
  • + * an instance of {@link javax.sql.DataSource} + *
  • + *
  • + * a JNDI name under which to obtain the {@link javax.sql.DataSource}; + * see also {@link EnvironmentSettings#JNDI_URL}, {@link EnvironmentSettings#JNDI_CLASS}, + * {@link EnvironmentSettings#JNDI_PREFIX} + *
  • + *
+ *

+ * See JPA 2 sections 9.4.3 and 8.2.1.5 + */ + String JAKARTA_NON_JTA_DATASOURCE = "jakarta.persistence.nonJtaDataSource"; + + /** + * Specifies the name of a JDBC driver to use to connect to the database. + *

+ * Used in conjunction with {@link #JAKARTA_JDBC_URL}, {@link #JAKARTA_JDBC_USER} + * and {@link #JAKARTA_JDBC_PASSWORD} to specify how to connect to the database. + *

+ * When connections are obtained from a {@link javax.sql.DataSource}, use + * either {@link #JAKARTA_JTA_DATASOURCE} or {@link #JAKARTA_NON_JTA_DATASOURCE} + * instead. + *

+ * See section 8.2.1.9 + */ + String JAKARTA_JDBC_DRIVER = "jakarta.persistence.jdbc.driver"; + + /** + * Specifies the JDBC connection URL to use to connect to the database. + *

+ * Used in conjunction with {@link #JAKARTA_JDBC_DRIVER}, {@link #JAKARTA_JDBC_USER} + * and {@link #JAKARTA_JDBC_PASSWORD} to specify how to connect to the database. + *

+ * When connections are obtained from a {@link javax.sql.DataSource}, use + * either {@link #JAKARTA_JTA_DATASOURCE} or {@link #JAKARTA_NON_JTA_DATASOURCE} + * instead. + *

+ * See section 8.2.1.9 + */ + String JAKARTA_JDBC_URL = "jakarta.persistence.jdbc.url"; + + /** + * Specifies the database user to use when connecting via JDBC. + *

+ * Used in conjunction with {@link #JAKARTA_JDBC_DRIVER}, {@link #JAKARTA_JDBC_URL} + * and {@link #JAKARTA_JDBC_PASSWORD} to specify how to connect to the database. + *

+ * Depending on the configured {@link ConnectionProvider}, the specified username might be used to: + *

    + *
  • + * create a JDBC connection using + * {@link java.sql.DriverManager#getConnection(String,java.util.Properties)} + * or {@link java.sql.Driver#connect(String,java.util.Properties)}, or + *
  • + *
  • + * obtain a JDBC connection from a datasource, using + * {@link javax.sql.DataSource#getConnection(String, String)}. + *
  • + *
+ *

+ * See section 8.2.1.9 + */ + String JAKARTA_JDBC_USER = "jakarta.persistence.jdbc.user"; + + /** + * Specifies the password to use when connecting via JDBC. + *

+ * Used in conjunction with {@link #JAKARTA_JDBC_DRIVER}, {@link #JAKARTA_JDBC_URL} + * and {@link #JAKARTA_JDBC_USER} to specify how to connect to the database. + *

+ * See JPA 2 section 8.2.1.9 + */ + String JAKARTA_JDBC_PASSWORD = "jakarta.persistence.jdbc.password"; + + /** + * Allows passing a specific {@link java.sql.Connection} instance to be used by + * {@link org.hibernate.tool.schema.spi.SchemaManagementTool} for the purpose of + * determining the {@link org.hibernate.dialect.Dialect}, and for performing + * {@link SchemaToolingSettings#JAKARTA_HBM2DDL_DATABASE_ACTION database actions} if requested. + *

+ * For {@code Dialect} resolution, {@value #JAKARTA_HBM2DDL_DB_NAME} and, optionally, + * {@value JAKARTA_HBM2DDL_DB_VERSION}, {@value #JAKARTA_HBM2DDL_DB_MAJOR_VERSION}, + * and {@value #JAKARTA_HBM2DDL_DB_MINOR_VERSION} can be used instead + * + * @see #JAKARTA_HBM2DDL_DB_NAME + * @see #JAKARTA_HBM2DDL_DB_VERSION + * @see #JAKARTA_HBM2DDL_DB_MAJOR_VERSION + * @see #JAKARTA_HBM2DDL_DB_MINOR_VERSION + */ + String JAKARTA_HBM2DDL_CONNECTION = "jakarta.persistence.schema-generation-connection"; + + /** + * Specifies the name of the database vendor (as would be reported by + * {@link java.sql.DatabaseMetaData#getDatabaseProductName}) for the purpose of + * determining the {@link org.hibernate.dialect.Dialect} to use. + *

+ * For cases when the name of the database vendor is not enough alone, a combination + * of {@value JAKARTA_HBM2DDL_DB_VERSION}, {@value #JAKARTA_HBM2DDL_DB_MAJOR_VERSION} + * {@value #JAKARTA_HBM2DDL_DB_MINOR_VERSION} can be used instead + * + * @see #JAKARTA_HBM2DDL_DB_VERSION + * @see #JAKARTA_HBM2DDL_DB_MAJOR_VERSION + * @see #JAKARTA_HBM2DDL_DB_MINOR_VERSION + * + * @implSpec {@link SchemaToolingSettings#JAKARTA_HBM2DDL_DATABASE_ACTION database actions} are not + * available when supplying just the name and versions + */ + String JAKARTA_HBM2DDL_DB_NAME = "jakarta.persistence.database-product-name"; + + /** + * Used in conjunction with {@value #JAKARTA_HBM2DDL_DB_NAME} for the purpose of + * determining the {@link org.hibernate.dialect.Dialect} to use when the name does + * not provide enough detail. + *

+ * The value is expected to match what would be returned from + * {@link java.sql.DatabaseMetaData#getDatabaseProductVersion()}) for the + * underlying database. + * + * @see #JAKARTA_HBM2DDL_DB_NAME + */ + String JAKARTA_HBM2DDL_DB_VERSION = "jakarta.persistence.database-product-version"; + + /** + * Used in conjunction with {@value #JAKARTA_HBM2DDL_DB_NAME} for the purpose of + * determining the {@link org.hibernate.dialect.Dialect} to use when the name does + * not provide enough detail. + *

+ * The value is expected to match what would be returned from + * {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion()}) for the underlying + * database. + * + * @see #JAKARTA_HBM2DDL_DB_NAME + */ + String JAKARTA_HBM2DDL_DB_MAJOR_VERSION = "jakarta.persistence.database-major-version"; + + /** + * Used in conjunction with {@value #JAKARTA_HBM2DDL_DB_NAME} for the purpose of + * determining the {@link org.hibernate.dialect.Dialect} to use when the name does + * not provide enough detail. + *

+ * The value is expected to match what would be returned from + * {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion()}) for the underlying + * database. + * + * @see #JAKARTA_HBM2DDL_DB_NAME + */ + String JAKARTA_HBM2DDL_DB_MINOR_VERSION = "jakarta.persistence.database-minor-version"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Hibernate settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Specifies the Hibernate {@linkplain org.hibernate.dialect.Dialect SQL dialect}, either + *

    + *
  • an instance of {@link org.hibernate.dialect.Dialect}, + *
  • a {@link Class} representing a class that extends {@code Dialect}, or + *
  • the name of a class that extends {@code Dialect}. + *
+ *

+ * By default, Hibernate will attempt to automatically determine the dialect from the + * {@linkplain #URL JDBC URL} and JDBC metadata, so this setting is not usually necessary. + * + * @apiNote As of Hibernate 6, this property should not be explicitly specified, + * except when using a custom user-written implementation of {@code Dialect}. + * Instead, applications should allow Hibernate to select the {@code Dialect} + * automatically. + * + * @see org.hibernate.dialect.Dialect + */ + String DIALECT = "hibernate.dialect"; + + /** + * Specifies additional {@link org.hibernate.engine.jdbc.dialect.spi.DialectResolver} + * implementations to register with the standard + * {@link org.hibernate.engine.jdbc.dialect.spi.DialectFactory}. + */ + String DIALECT_RESOLVERS = "hibernate.dialect_resolvers"; + + /** + * Specifies a {@link ConnectionProvider} + * to use for obtaining JDBC connections, either: + *

    + *
  • an instance of {@code ConnectionProvider}, + *
  • a {@link Class} representing a class that implements + * {@code ConnectionProvider}, or + *
  • the name of a class that implements {@code ConnectionProvider}. + *
+ *

+ * The term {@code "class"} appears in the setting name due to legacy reasons; + * however it can accept instances. + */ + String CONNECTION_PROVIDER = "hibernate.connection.provider_class"; + + /** + * Specifies the maximum number of inactive connections for the built-in + * {@linkplain org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl + * connection pool}. + * + * @settingDefault 20 + */ + String POOL_SIZE = "hibernate.connection.pool_size"; + + /** + * Specified the JDBC transaction isolation level. + */ + String ISOLATION = "hibernate.connection.isolation"; + + /** + * Controls the autocommit mode of JDBC connections obtained from any + * {@link ConnectionProvider} implementation + * which respects this setting, which the built-in implementations do, except for + * {@link org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl}. + */ + String AUTOCOMMIT = "hibernate.connection.autocommit"; + + /** + * Indicates that Connections obtained from the configured {@link ConnectionProvider} have + * auto-commit already disabled when they are acquired. + *

+ * It is inappropriate to set this value to {@code true} when the Connections returned by + * the provider do not, in fact, have auto-commit disabled. Doing so may lead to Hibernate + * executing SQL operations outside the scope of any transaction. + * + * @apiNote By default, Hibernate calls {@link java.sql.Connection#setAutoCommit(boolean)} on + * newly-obtained connections. This setting allows to circumvent that call (as well as other + * operations) in the interest of performance. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyConnectionProviderDisablesAutoCommit(boolean) + * + * @since 5.2.10 + */ + String CONNECTION_PROVIDER_DISABLES_AUTOCOMMIT= "hibernate.connection.provider_disables_autocommit"; + + /** + * A prefix for properties specifying arbitrary JDBC connection properties. These + * properties are simply passed along to the provider when creating a connection. + *

+ * For example, declaring {@code hibernate.connection.foo=bar} tells Hibernate to + * append {@code foo=bar} to the JDBC connection URL. + */ + String CONNECTION_PREFIX = "hibernate.connection"; + + /** + * Specifies a {@link org.hibernate.resource.jdbc.spi.StatementInspector} + * implementation associated with the {@link org.hibernate.SessionFactory}, + * either: + *

    + *
  • an instance of {@code StatementInspector}, + *
  • a {@link Class} representing an class that implements {@code StatementInspector}, or + *
  • the name of a class that implements {@code StatementInspector}. + *
+ * + * @see org.hibernate.boot.SessionFactoryBuilder#applyStatementInspector(StatementInspector) + * + * @since 5.0 + */ + String STATEMENT_INSPECTOR = "hibernate.session_factory.statement_inspector"; + + /** + * Enables logging of generated SQL to the console. + * + * @settingDefault {@code false} + */ + String SHOW_SQL = "hibernate.show_sql"; + + /** + * Enables formatting of SQL logged to the console. + * + * @settingDefault {@code false} + */ + String FORMAT_SQL = "hibernate.format_sql"; + + /** + * Enables highlighting of SQL logged to the console using ANSI escape codes. + * + * @settingDefault {@code false} + */ + String HIGHLIGHT_SQL = "hibernate.highlight_sql"; + + /** + * Specifies a duration in milliseconds defining the minimum query execution time that + * characterizes a "slow" query. Any SQL query which takes longer than this amount of + * time to execute will be logged. + *

+ * A value of {@code 0}, the default, disables logging of "slow" queries. + * + * @see org.hibernate.stat.Statistics#getSlowQueries() + */ + String LOG_SLOW_QUERY = "hibernate.log_slow_query"; + + /** + * Specifies that comments should be added to the generated SQL. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applySqlComments(boolean) + */ + String USE_SQL_COMMENTS = "hibernate.use_sql_comments"; + + /** + * Gives the JDBC driver a hint as to the number of rows that should be fetched + * from the database when more rows are needed. If {@code 0}, the JDBC driver's + * default settings will be used. + * + * @see java.sql.PreparedStatement#setFetchSize(int) + * @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcFetchSize(int) + * @see org.hibernate.ScrollableResults#setFetchSize(int) + * + * @settingDefault {@code 0} + */ + String STATEMENT_FETCH_SIZE = "hibernate.jdbc.fetch_size"; + + /** + * Controls how Hibernate should handle scrollable results -

    + *
  • + * {@code true} indicates that {@linkplain java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE insensitive} scrolling can be used + *
  • + *
  • + * {@code false} indicates that {@linkplain java.sql.ResultSet#TYPE_SCROLL_SENSITIVE sensitive} scrolling must be used + *
  • + *
+ * + * @settingDefault {@code true} if the underlying driver supports scrollable results + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyScrollableResultsSupport(boolean) + * @see Query#scroll + * @see ExtractedDatabaseMetaData#supportsScrollableResults() + */ + String USE_SCROLLABLE_RESULTSET = "hibernate.jdbc.use_scrollable_resultset"; + + /** + * Controls whether to use JDBC markers (`?`) or dialect native markers for parameters + * within {@linkplain java.sql.PreparedStatement preparable} SQL statements. + * + * @implNote {@code False} by default, indicating standard JDBC parameter markers (`?`) + * are used. Set to {@code true} to use the Dialect's native markers, if any. For + * Dialects without native markers, the standard JDBC strategy is used. + * + * @see ParameterMarkerStrategy + * @see org.hibernate.dialect.Dialect#getNativeParameterMarkerStrategy() + * + * @since 6.2 + */ + @Incubating + String DIALECT_NATIVE_PARAM_MARKERS = "hibernate.dialect.native_param_markers"; + + /** + * When enabled, specifies that Hibernate should not use contextual LOB creation. + * + * @see org.hibernate.engine.jdbc.LobCreator + * @see org.hibernate.engine.jdbc.LobCreationContext + */ + String NON_CONTEXTUAL_LOB_CREATION = "hibernate.jdbc.lob.non_contextual_creation"; + + /** + * When enabled, specifies that JDBC statement warnings should be logged. + *

+ * The default is determined by + * {@link org.hibernate.dialect.Dialect#isJdbcLogWarningsEnabledByDefault()}. + * + * @see java.sql.Statement#getWarnings() + * + * @since 5.1 + */ + String LOG_JDBC_WARNINGS = "hibernate.jdbc.log.warnings"; + + /** + * Specifies the {@linkplain java.util.TimeZone time zone} to use in the JDBC driver, + * which is supposed to match the database timezone. + *

+ * This is the timezone what will be passed to + * {@link java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)} + * {@link java.sql.PreparedStatement#setTime(int, java.sql.Time, java.util.Calendar)}, + * {@link java.sql.ResultSet#getTimestamp(int, Calendar)}, and + * {@link java.sql.ResultSet#getTime(int, Calendar)} when binding parameters. + *

+ * The time zone may be given as: + *

    + *
  • an instance of {@link java.util.TimeZone}, + *
  • an instance of {@link java.time.ZoneId}, or + *
  • a time zone ID string to be passed to {@link java.time.ZoneId#of(String)}. + *
+ *

+ * By default, the {@linkplain java.util.TimeZone#getDefault() JVM default time zone} + * is assumed by the JDBC driver. + * + * @since 5.2.3 + */ + String JDBC_TIME_ZONE = "hibernate.jdbc.time_zone"; + + /** + * Specifies that generated primary keys may be retrieved using the JDBC 3 + * {@link java.sql.PreparedStatement#getGeneratedKeys()} operation. + *

+ * Usually, performance will be improved if this behavior is enabled, assuming + * the JDBC driver supports {@code getGeneratedKeys()}. + * + * @see java.sql.PreparedStatement#getGeneratedKeys + * @see org.hibernate.boot.SessionFactoryBuilder#applyGetGeneratedKeysSupport(boolean) + */ + String USE_GET_GENERATED_KEYS = "hibernate.jdbc.use_get_generated_keys"; + + /** + * Specifies how Hibernate should manage JDBC connections in terms of acquisition + * and release, either: + *

    + *
  • an instance of the enumeration + * {@link org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode}, + * or + *
  • the name of one of its instances. + *
+ *

+ * The default is {@code DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION}. + * + * @see org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode + * @see org.hibernate.boot.SessionFactoryBuilder#applyConnectionHandlingMode(PhysicalConnectionHandlingMode) + * + * @since 5.2 + */ + String CONNECTION_HANDLING = "hibernate.connection.handling_mode"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Deprecated Hibernate settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * @deprecated The JPA-standard setting {@link #JAKARTA_JDBC_DRIVER} is now preferred. + */ + @Deprecated + String DRIVER = "hibernate.connection.driver_class"; + + /** + * @deprecated The JPA-standard setting {@link #JAKARTA_JDBC_URL} is now preferred. + */ + @Deprecated + String URL = "hibernate.connection.url"; + + /** + * @see #PASS + * + * @deprecated The JPA-standard setting {@link #JAKARTA_JDBC_USER} is now preferred. + */ + @Deprecated + String USER = "hibernate.connection.username"; + + /** + * @see #USER + * + * @deprecated The JPA-standard setting {@link #JAKARTA_JDBC_USER} is now preferred. + */ + @Deprecated + String PASS = "hibernate.connection.password"; + + /** + * @see javax.sql.DataSource + * + * @deprecated The JPA-standard {@link #JAKARTA_JTA_DATASOURCE} or {@link #JAKARTA_JTA_DATASOURCE} setting + * is now preferred. + */ + @Deprecated + String DATASOURCE = "hibernate.connection.datasource"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Legacy JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * @deprecated Use {@link #JAKARTA_JTA_DATASOURCE} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_JTA_DATASOURCE = "javax.persistence.jtaDataSource"; + + /** + * @deprecated Use {@link #JAKARTA_NON_JTA_DATASOURCE} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_NON_JTA_DATASOURCE = "javax.persistence.nonJtaDataSource"; + + /** + * @deprecated Use {@link #JAKARTA_JDBC_DRIVER} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_JDBC_DRIVER = "javax.persistence.jdbc.driver"; + + /** + * @deprecated Use {@link #JAKARTA_JDBC_URL} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_JDBC_URL = "javax.persistence.jdbc.url"; + + /** + * @deprecated Use {@link #JAKARTA_JDBC_USER} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_JDBC_USER = "javax.persistence.jdbc.user"; + + /** + * @deprecated Use {@link #JAKARTA_JDBC_PASSWORD} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_JDBC_PASSWORD = "javax.persistence.jdbc.password"; + + /** + * @deprecated Use {@link #JAKARTA_HBM2DDL_CONNECTION} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_CONNECTION = "javax.persistence.schema-generation-connection"; + + /** + * @see #DIALECT_DB_VERSION + * @see #DIALECT_DB_MAJOR_VERSION + * @see #DIALECT_DB_MINOR_VERSION + * + * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_NAME} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String DIALECT_DB_NAME = "javax.persistence.database-product-name"; + + /** + * @see #DIALECT_DB_NAME + * + * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_VERSION} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String DIALECT_DB_VERSION = "javax.persistence.database-product-version"; + + /** + * @see #DIALECT_DB_NAME + * @see #DIALECT_DB_MINOR_VERSION + * + * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_MAJOR_VERSION} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String DIALECT_DB_MAJOR_VERSION = "javax.persistence.database-major-version"; + + /** + * @see #DIALECT_DB_NAME + * @see #DIALECT_DB_MAJOR_VERSION + * @see org.hibernate.engine.jdbc.dialect.spi.DialectResolver + * + * @deprecated Use {@link #JAKARTA_HBM2DDL_DB_MINOR_VERSION} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String DIALECT_DB_MINOR_VERSION = "javax.persistence.database-minor-version"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/JpaComplianceSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/JpaComplianceSettings.java new file mode 100644 index 0000000000..444bb38d3a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/JpaComplianceSettings.java @@ -0,0 +1,217 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +/** + * @author Steve Ebersole + */ +public interface JpaComplianceSettings { + /** + * Specifies a default value for all {@link org.hibernate.jpa.spi.JpaCompliance} + * flags. Each individual flag may still be overridden by explicitly specifying + * its specific configuration property. + * + * @settingDefault {@code true} with JPA bootstrapping; {@code false} otherwise. + * + * @see #JPA_TRANSACTION_COMPLIANCE + * @see #JPA_QUERY_COMPLIANCE + * @see #JPA_LIST_COMPLIANCE + * @see #JPA_ORDER_BY_MAPPING_COMPLIANCE + * @see #JPA_CLOSED_COMPLIANCE + * @see #JPA_PROXY_COMPLIANCE + * @see #JPA_CACHING_COMPLIANCE + * @see #JPA_ID_GENERATOR_GLOBAL_SCOPE_COMPLIANCE + * @see #JPA_LOAD_BY_ID_COMPLIANCE + * + * @since 6.0 + */ + String JPA_COMPLIANCE = "hibernate.jpa.compliance"; + + /** + * When enabled, specifies that the Hibernate {@link org.hibernate.Transaction} + * should behave according to the semantics defined by the JPA specification for + * an {@link jakarta.persistence.EntityTransaction}. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @see org.hibernate.jpa.spi.JpaCompliance#isJpaTransactionComplianceEnabled() + * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaTransactionCompliance(boolean) + * + * @since 5.3 + */ + String JPA_TRANSACTION_COMPLIANCE = "hibernate.jpa.compliance.transaction"; + + /** + * Controls whether Hibernate’s handling of {@link jakarta.persistence.Query} + * (JPQL, Criteria and native) should strictly follow the requirements defined + * in the Jakarta Persistence specification, both in terms of JPQL validation + * and behavior of {@link jakarta.persistence.Query} method implementations. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @apiNote When disabled, allows the many useful features of HQL + * + * @see org.hibernate.jpa.spi.JpaCompliance#isJpaQueryComplianceEnabled() + * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaQueryCompliance(boolean) + * + * @since 5.3 + */ + String JPA_QUERY_COMPLIANCE = "hibernate.jpa.compliance.query"; + + /** + * Controls whether Hibernate should treat what it would usually consider a + * {@linkplain org.hibernate.collection.spi.PersistentBag "bag"}, that is, a + * list with no index column, whose element order is not persistent, as a true + * {@link org.hibernate.collection.spi.PersistentList list} with an index column + * and a persistent element order. + * + * @apiNote If enabled, Hibernate will recognize it as a list where the + * {@link jakarta.persistence.OrderColumn} annotation is simply missing + * (and its defaults will apply). + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @see org.hibernate.jpa.spi.JpaCompliance#isJpaListComplianceEnabled() + * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaListCompliance(boolean) + * + * @since 5.3 + * + * @deprecated Use {@link MappingSettings#DEFAULT_LIST_SEMANTICS} instead. The specification + * actually leaves this behavior undefined, saying that portable applications + * should not rely on any specific behavior for a {@link java.util.List} with + * no {@code @OrderColumn}. + */ + @Deprecated( since = "6.0" ) + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_LIST_COMPLIANCE = "hibernate.jpa.compliance.list"; + + /** + * JPA specifies that items occurring in {@link jakarta.persistence.OrderBy} + * lists must be references to entity attributes, whereas Hibernate, by default, + * allows more complex expressions. + * + * @apiNote If enabled, an exception is thrown for items which are not entity attribute + * references. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @see org.hibernate.jpa.spi.JpaCompliance#isJpaOrderByMappingComplianceEnabled() + * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaOrderByMappingCompliance(boolean) + * + * @since 6.0 + */ + String JPA_ORDER_BY_MAPPING_COMPLIANCE = "hibernate.jpa.compliance.orderby"; + + /** + * JPA specifies that an {@link IllegalStateException} must be thrown by + * {@link jakarta.persistence.EntityManager#close()} and + * {@link jakarta.persistence.EntityManagerFactory#close()} if the object has + * already been closed. By default, Hibernate treats any additional call to + * {@code close()} as a noop. + * + * @apiNote When enabled, this setting forces Hibernate to throw an exception if + * {@code close()} is called on an instance that was already closed. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @see org.hibernate.jpa.spi.JpaCompliance#isJpaClosedComplianceEnabled() + * @see org.hibernate.boot.SessionFactoryBuilder#enableJpaClosedCompliance(boolean) + * + * @since 5.3 + */ + String JPA_CLOSED_COMPLIANCE = "hibernate.jpa.compliance.closed"; + + /** + * The JPA specification insists that an + * {@link jakarta.persistence.EntityNotFoundException} must be thrown whenever + * an uninitialized entity proxy with no corresponding row in the database is + * accessed. For most programs, this results in many completely unnecessary + * round trips to the database. + *

+ * Traditionally, Hibernate does not initialize an entity proxy when its + * identifier attribute is accessed, since the identifier value is already + * known and held in the proxy instance. This behavior saves the round trip + * to the database. + * + * @apiNote When enabled, this setting forces Hibernate to initialize the entity proxy + * when its identifier is accessed. Clearly, this setting is not recommended. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @see org.hibernate.jpa.spi.JpaCompliance#isJpaProxyComplianceEnabled() + * + * @since 5.2.13 + */ + String JPA_PROXY_COMPLIANCE = "hibernate.jpa.compliance.proxy"; + + /** + * By default, Hibernate uses second-level cache invalidation for entities + * with {@linkplain jakarta.persistence.SecondaryTable secondary tables} + * in order to avoid the possibility of inconsistent cached data in the + * case where different transactions simultaneously update different table + * rows corresponding to the same entity instance. + *

+ * The Jakarta Persistence TCK, requires that entities with secondary + * tables be immediately cached in the second-level cache rather than + * invalidated and re-cached on a subsequent read. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @apiNote Hibernate's default behavior here is safer and more careful + * than the behavior mandated by the TCK but YOLO + * + * @see org.hibernate.jpa.spi.JpaCompliance#isJpaCacheComplianceEnabled() + * @see org.hibernate.persister.entity.AbstractEntityPersister#isCacheInvalidationRequired() + * + * @since 5.3 + */ + String JPA_CACHING_COMPLIANCE = "hibernate.jpa.compliance.caching"; + + /** + * Determines whether the scope of any identifier generator name specified + * via {@link jakarta.persistence.TableGenerator#name()} or + * {@link jakarta.persistence.SequenceGenerator#name()} is considered global + * to the persistence unit, or local to the entity in which identifier generator + * is defined. + * + * @apiNote If enabled, the name will be considered globally scoped, and so the existence + * of two different generators with the same name will be considered a collision, + * and will result in an exception during bootstrap. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @see org.hibernate.jpa.spi.JpaCompliance#isGlobalGeneratorScopeEnabled() + * + * @since 5.2.17 + */ + String JPA_ID_GENERATOR_GLOBAL_SCOPE_COMPLIANCE = "hibernate.jpa.compliance.global_id_generators"; + + /** + * Determines if an identifier value passed to + * {@link jakarta.persistence.EntityManager#find} or + * {@link jakarta.persistence.EntityManager#getReference} may be + * {@linkplain org.hibernate.type.descriptor.java.JavaType#coerce coerced} to + * the identifier type declared by the entity. For example, an {@link Integer} + * argument might be widened to {@link Long}. + * + * @settingDefault {@link #JPA_COMPLIANCE} + * + * @apiNote When enabled, coercion is disallowed, as required by the JPA specification. + * Hibernate's default (here non-compliant) behavior is to allow the coercion. + * + * @see org.hibernate.jpa.spi.JpaCompliance#isLoadByIdComplianceEnabled() + * + * @since 6.0 + */ + String JPA_LOAD_BY_ID_COMPLIANCE = "hibernate.jpa.compliance.load_by_id"; + + /** + * @deprecated Prefer {@link #JPA_QUERY_COMPLIANCE} + */ + @Deprecated + String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ManagedBeanSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/ManagedBeanSettings.java new file mode 100644 index 0000000000..c5bef3962a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/ManagedBeanSettings.java @@ -0,0 +1,105 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +/** + * @author Steve Ebersole + */ +public interface ManagedBeanSettings { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Used to pass a CDI {@link jakarta.enterprise.inject.spi.BeanManager} to + * Hibernate. + *

+ * According to the JPA specification, the {@code BeanManager} should be + * passed at boot time and be ready for immediate use at that time. But + * not all environments can do this (WildFly, for example). To accommodate + * such environments, Hibernate provides two options:

    + *
  1. A proprietary CDI extension SPI (which has been proposed to the CDI + * spec group as a standard option) which can be used to provide delayed + * {@code BeanManager} access: to use this solution, the reference passed + * as the {@code BeanManager} during bootstrap should be typed as + * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager}. + *
  2. Delayed access to the {@code BeanManager} reference: here, Hibernate + * will not access the reference passed as the {@code BeanManager} during + * bootstrap until it is first needed. Note, however, that this has the + * effect of delaying the detection of any deployment problems until after + * bootstrapping. + *
+ * + * This setting is used to configure access to the {@code BeanManager}, + * either directly, or via + * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager}. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyBeanManager(Object) + */ + String JAKARTA_CDI_BEAN_MANAGER = "jakarta.persistence.bean.manager"; + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Hibernate settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Identifies a {@link org.hibernate.resource.beans.container.spi.BeanContainer} + * to be used. + *

+ * Note that for CDI-based containers setting this is not necessary - simply + * pass the {@link jakarta.enterprise.inject.spi.BeanManager} to use via + * {@link #CDI_BEAN_MANAGER} and optionally specify {@link #DELAY_CDI_ACCESS}. + * This setting useful to integrate non-CDI bean containers such as Spring. + * + * @since 5.3 + */ + String BEAN_CONTAINER = "hibernate.resource.beans.container"; + + /** + * Used in conjunction with {@value #BEAN_CONTAINER} when CDI is used. + *

+ * By default, to be JPA spec compliant, Hibernate should access the CDI + * {@link jakarta.enterprise.inject.spi.BeanManager} while bootstrapping the + * {@link org.hibernate.SessionFactory}. In some cases however this can lead + * to a chicken/egg situation where the JPA provider immediately accesses the + * {@code BeanManager} when managed beans are awaiting JPA PU injection. + *

+ * This setting tells Hibernate to delay accessing until first use. + *

+ * This setting has the decided downside that bean config problems will not + * be done at deployment time, but will instead manifest at runtime. For this + * reason, the preferred means for supplying a CDI BeanManager is to provide + * an implementation of + * {@link org.hibernate.resource.beans.container.spi.ExtendedBeanManager} which + * gives Hibernate a callback when the {@code BeanManager} is ready for use. + * + * @since 5.0.8 + */ + String DELAY_CDI_ACCESS = "hibernate.delay_cdi_access"; + + /** + * Controls whether Hibernate can try to create beans other than converters + * and listeners using CDI. Only meaningful when a CDI {@link #BEAN_CONTAINER container} + * is used. + *

+ * By default, Hibernate will only attempt to create converter and listener beans using CDI. + * + * @since 6.2 + */ + String ALLOW_EXTENSIONS_IN_CDI = "hibernate.cdi.extensions"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Legacy JPA setting + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * @deprecated Use {@link #JAKARTA_CDI_BEAN_MANAGER} instead + */ + @Deprecated + String CDI_BEAN_MANAGER = "javax.persistence.bean.manager"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/MappingSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/MappingSettings.java new file mode 100644 index 0000000000..9bf38a7a0f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/MappingSettings.java @@ -0,0 +1,572 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.Incubating; +import org.hibernate.Remove; +import org.hibernate.SessionFactory; +import org.hibernate.annotations.ListIndexBase; +import org.hibernate.annotations.Nationalized; +import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling; +import org.hibernate.boot.registry.selector.spi.StrategySelector; +import org.hibernate.dialect.Dialect; +import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy; +import org.hibernate.id.enhanced.StandardOptimizerDescriptor; +import org.hibernate.metamodel.CollectionClassification; +import org.hibernate.type.WrapperArrayHandling; +import org.hibernate.type.format.FormatMapper; + +import jakarta.persistence.Column; +import jakarta.persistence.DiscriminatorColumn; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OrderColumn; + +/** + * @author Steve Ebersole + */ +public interface MappingSettings { + /** + * A default database catalog name to use for unqualified database + * object (table, sequence, ...) names + * + * @see org.hibernate.boot.MetadataBuilder#applyImplicitCatalogName + */ + String DEFAULT_CATALOG = "hibernate.default_catalog"; + + /** + * A default database schema (owner) name to use for unqualified + * database object (table, sequence, ...) names + * + * @see org.hibernate.boot.MetadataBuilder#applyImplicitSchemaName + */ + String DEFAULT_SCHEMA = "hibernate.default_schema"; + + /** + * Setting that indicates whether to build the JPA types, either:

    + *
  • + * enabled - Do the build + *
  • + *
  • + * disabled - Do not do the build + *
  • + *
  • + * ignoreUnsupported - Do the build, but ignore any non-JPA + * features that would otherwise result in a failure. + *
  • + *
+ */ + String JPA_METAMODEL_POPULATION = "hibernate.jpa.metamodel.population"; + + /** + * Setting that controls whether we seek out JPA "static metamodel" classes + * and populate them, either:
    + *
  • + * enabled - Do the population + *
  • + *
  • + * disabled - Do not do the population + *
  • + *
  • + * skipUnsupported - Do the population, but ignore any non-JPA + * features that would otherwise result in the population failing. + *
  • + *
+ */ + String STATIC_METAMODEL_POPULATION = "hibernate.jpa.static_metamodel.population"; + + /** + * When enabled, all database identifiers are quoted. + *

+ * Corollary to the JPA {@code } element within + * the {@code orm.xml} {@code } element, but + * offered as a global flag. + * + * @settingDefault {@code false} + */ + String GLOBALLY_QUOTED_IDENTIFIERS = "hibernate.globally_quoted_identifiers"; + + /** + * Controls whether column-definitions ({@link Column#columnDefinition}, + * {@link JoinColumn#columnDefinition}, etc.) should be auto-quoted as part of + * {@linkplain #GLOBALLY_QUOTED_IDENTIFIERS global quoting}. + *

+ * When {@linkplain #GLOBALLY_QUOTED_IDENTIFIERS global quoting} is enabled, JPA + * states + * that column-definitions are subject to quoting. However, this can lead to problems + * with definitions such as {@code @Column(..., columnDefinition="INTEGER DEFAULT 20")}. + * + * @settingDefault {@code false} to avoid the potential problems quoting non-trivial + * column-definitions. + */ + String GLOBALLY_QUOTED_IDENTIFIERS_SKIP_COLUMN_DEFINITIONS = "hibernate.globally_quoted_identifiers_skip_column_definitions"; + + /** + * Specifies whether to automatically quote any names that are deemed keywords + * on the underlying database. + * + * @settingDefault {@code false} - auto-quoting of SQL keywords is disabled by default. + * + * @since 5.0 + */ + String KEYWORD_AUTO_QUOTING_ENABLED = "hibernate.auto_quote_keyword"; + + /** + * When a generator specifies an increment-size and an optimizer was not explicitly + * specified, which of the "pooled" optimizers should be preferred? Can specify an + * optimizer short name or the name of a class which implements + * {@link org.hibernate.id.enhanced.Optimizer}. + * + * @settingDefault {@link StandardOptimizerDescriptor#POOLED} + */ + String PREFERRED_POOLED_OPTIMIZER = "hibernate.id.optimizer.pooled.preferred"; + + /** + * Determines if the identifier value stored in the database table backing a + * {@linkplain jakarta.persistence.TableGenerator table generator} is the last + * value returned by the identifier generator, or the next value to be returned. + * + * @settingDefault The value stored in the database table is the last generated value + * + * @since 5.3 + */ + String TABLE_GENERATOR_STORE_LAST_USED = "hibernate.id.generator.stored_last_used"; + + /** + * This setting defines the {@link org.hibernate.id.SequenceMismatchStrategy} used + * when Hibernate detects a mismatch between a sequence configuration in an entity + * mapping and its database sequence object counterpart. + *

+ * Possible values are {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION}, + * {@link org.hibernate.id.SequenceMismatchStrategy#LOG}, + * {@link org.hibernate.id.SequenceMismatchStrategy#FIX} + * and {@link org.hibernate.id.SequenceMismatchStrategy#NONE}. + * + * @settingDefault {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION}, meaning + * that an exception is thrown when such a conflict is detected. + * + * @since 5.4 + */ + String SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY = "hibernate.id.sequence.increment_size_mismatch_strategy"; + + /** + * Specifies the preferred JDBC type for storing boolean values. + *

+ * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, + * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. + *

+ * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant + * field, for example, {@code hibernate.type.preferred_boolean_jdbc_type=BIT}. + * + * @settingDefault {@linkplain Dialect#getPreferredSqlTypeCodeForBoolean dialect-specific type code} + * + * @since 6.0 + */ + @Incubating + String PREFERRED_BOOLEAN_JDBC_TYPE = "hibernate.type.preferred_boolean_jdbc_type"; + + /** + * The preferred JDBC type to use for storing {@link java.util.UUID} values. + *

+ * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, + * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. + *

+ * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant + * field, for example, {@code hibernate.type.preferred_uuid_jdbc_type=CHAR}. + * + * @settingDefault {@link org.hibernate.type.SqlTypes#UUID}. + * + * @since 6.0 + */ + @Incubating + String PREFERRED_UUID_JDBC_TYPE = "hibernate.type.preferred_uuid_jdbc_type"; + + /** + * The preferred JDBC type to use for storing {@link java.time.Duration} values. + *

+ * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, + * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. + *

+ * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant + * field, for example, {@code hibernate.type.preferred_duration_jdbc_type=INTERVAL_SECOND}. + * + * @settingDefault {@link org.hibernate.type.SqlTypes#NUMERIC} + * + * @since 6.0 + */ + @Incubating + String PREFERRED_DURATION_JDBC_TYPE = "hibernate.type.preferred_duration_jdbc_type"; + + /** + * Specifies the preferred JDBC type for storing {@link java.time.Instant} values. + *

+ * Can be overridden locally using {@link org.hibernate.annotations.JdbcType}, + * {@link org.hibernate.annotations.JdbcTypeCode}, and friends. + *

+ * Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant + * field, for example, {@code hibernate.type.preferred_instant_jdbc_type=TIMESTAMP}. + * + * @settingDefault {@link org.hibernate.type.SqlTypes#TIMESTAMP_UTC}. + * + * @since 6.0 + */ + @Incubating + String PREFERRED_INSTANT_JDBC_TYPE = "hibernate.type.preferred_instant_jdbc_type"; + + /** + * Specifies a {@link org.hibernate.type.format.FormatMapper} used for JSON + * serialization and deserialization, either: + *

    + *
  • an instance of {@code FormatMapper}, + *
  • a {@link Class} representing a class that implements {@code FormatMapper}, + *
  • the name of a class that implements {@code FormatMapper}, or + *
  • one of the shorthand constants {@code jackson} or {@code jsonb}. + *
+ *

+ * By default, the first of the possible providers that is available at runtime is + * used, according to the listing order. + * + * @since 6.0 + * @see org.hibernate.boot.SessionFactoryBuilder#applyJsonFormatMapper(FormatMapper) + */ + @Incubating + String JSON_FORMAT_MAPPER = "hibernate.type.json_format_mapper"; + + /** + * Specifies a {@link org.hibernate.type.format.FormatMapper} used for XML + * serialization and deserialization, either: + *

    + *
  • an instance of {@code FormatMapper}, + *
  • a {@link Class} representing a class that implements {@code FormatMapper}, + *
  • the name of a class that implements {@code FormatMapper}, or + *
  • one of the shorthand constants {@code jackson} or {@code jaxb}. + *
+ *

+ * By default, the first of the possible providers that is available at runtime is + * used, according to the listing order. + * + * @since 6.0.1 + * @see org.hibernate.boot.SessionFactoryBuilder#applyXmlFormatMapper(FormatMapper) + */ + @Incubating + String XML_FORMAT_MAPPER = "hibernate.type.xml_format_mapper"; + + /** + * Configurable control over how to handle {@code Byte[]} and {@code Character[]} types + * encountered in the application domain model. Allowable semantics are defined by + * {@link WrapperArrayHandling}. Accepted values include:

    + *
  1. {@link WrapperArrayHandling} instance
  2. + *
  3. case-insensitive name of a {@link WrapperArrayHandling} instance (e.g. {@code allow})
  4. + *
+ * + * @since 6.2 + */ + @Incubating + String WRAPPER_ARRAY_HANDLING = "hibernate.type.wrapper_array_handling"; + + /** + * Specifies the default strategy for storage of the timezone information for the zoned + * datetime types {@link java.time.OffsetDateTime} and {@link java.time.ZonedDateTime}. + * The possible options for this setting are enumerated by + * {@link org.hibernate.annotations.TimeZoneStorageType}. + * + * @apiNote For backward compatibility with older versions of Hibernate, set this property to + * {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE NORMALIZE}. + * + * @settingDefault {@link org.hibernate.annotations.TimeZoneStorageType#DEFAULT DEFAULT}, + * which guarantees that the {@linkplain java.time.OffsetDateTime#toInstant() instant} + * represented by a zoned datetime type is preserved by a round trip to the database. + * It does not guarantee that the time zone or offset is preserved. + * + * @see org.hibernate.annotations.TimeZoneStorageType + * @see org.hibernate.annotations.TimeZoneStorage + * + * @since 6.0 + */ + String TIMEZONE_DEFAULT_STORAGE = "hibernate.timezone.default_storage"; + + /** + * Used to specify the {@link org.hibernate.boot.model.naming.ImplicitNamingStrategy} + * class to use. The following shortcut names are defined for this setting: + *
    + *
  • {@code "default"} and {@code "jpa"} are an abbreviations for + * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl} + *
  • {@code "legacy-jpa"} is an abbreviation for + * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl} + *
  • {@code "legacy-hbm"} is an abbreviation for + * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl} + *
  • {@code "component-path"} is an abbreviation for + * {@link org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl} + *
+ * + * @settingDefault {@code "default"} + * + * @see org.hibernate.boot.MetadataBuilder#applyImplicitNamingStrategy + * + * @since 5.0 + */ + String IMPLICIT_NAMING_STRATEGY = "hibernate.implicit_naming_strategy"; + + /** + * Specifies the {@link org.hibernate.boot.model.naming.PhysicalNamingStrategy} to use. + * + * @settingDefault {@link org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl}, + * in which case physical names are taken to be identical to logical names. + * + * @see org.hibernate.boot.MetadataBuilder#applyPhysicalNamingStrategy + * + * @since 5.0 + */ + String PHYSICAL_NAMING_STRATEGY = "hibernate.physical_naming_strategy"; + + /** + * An implicit naming strategy for database structures (tables, sequences) related + * to identifier generators. + *

+ * Resolution uses the {@link org.hibernate.boot.registry.selector.spi.StrategySelector} + * service and accepts any of the forms discussed on + * {@link StrategySelector#resolveDefaultableStrategy(Class, Object, java.util.concurrent.Callable)}. + *

+ * The recognized short names being:

    + *
  • {@value org.hibernate.id.enhanced.SingleNamingStrategy#STRATEGY_NAME}
  • + *
  • {@value org.hibernate.id.enhanced.LegacyNamingStrategy#STRATEGY_NAME}
  • + *
  • {@value org.hibernate.id.enhanced.StandardNamingStrategy#STRATEGY_NAME}
  • + *
+ * + * @settingDefault {@link org.hibernate.id.enhanced.StandardNamingStrategy} + * + * @since 6 + * + * @see ImplicitDatabaseObjectNamingStrategy + */ + @Incubating + String ID_DB_STRUCTURE_NAMING_STRATEGY = "hibernate.id.db_structure_naming_strategy"; + + /** + * Used to specify the {@link org.hibernate.boot.model.relational.ColumnOrderingStrategy} + * class to use. The following shortcut names are defined for this setting: + *
    + *
  • {@code "default"} is an abbreviations for + * {@link org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard} + *
  • {@code "legacy"} is an abbreviation for + * {@link org.hibernate.boot.model.relational.ColumnOrderingStrategyLegacy} + *
+ * + * @settingDefault {@code "default"} + * + * @see org.hibernate.boot.MetadataBuilder#applyColumnOrderingStrategy + * + * @since 6.2 + */ + String COLUMN_ORDERING_STRATEGY = "hibernate.column_ordering_strategy"; + + /** + * Specifies the order in which metadata sources should be processed, is a delimited list + * of values defined by {@link MetadataSourceType}. + * + * @settingDefault {@code "hbm,class"}, which indicates that {@code hbm.xml} files + * should be processed first, followed by annotations and {@code orm.xml} files. + * + * @see MetadataSourceType + * @see org.hibernate.boot.MetadataBuilder#applySourceProcessOrdering(MetadataSourceType...) + * + * @deprecated {@code hbm.xml} mappings are no longer supported, making this attribute irrelevant + */ + @SuppressWarnings("DeprecatedIsStillUsed") + @Deprecated(since = "6", forRemoval = true) + String ARTIFACT_PROCESSING_ORDER = "hibernate.mapping.precedence"; + + /** + * Whether XML mappings should be processed. + * + * @apiNote This is a performance optimization appropriate when mapping details + * are defined exclusively using annotations. + * + * @settingDefault {@code true} - XML mappings are processed + * + * @since 5.4.1 + */ + String XML_MAPPING_ENABLED = "hibernate.xml_mapping_enabled"; + + /** + * Specifies the {@link CollectionClassification} to use for a plural attribute + * typed as {@link java.util.List} with no explicit list index details + * ({@link OrderColumn}, {@link ListIndexBase}, etc.). + *

+ * Accepts any of: + *

    + *
  • an instance of {@code CollectionClassification} + *
  • the (case insensitive) name of a {@code CollectionClassification} (list e.g.) + *
  • a {@link Class} representing either {@link java.util.List} or {@link java.util.Collection} + *
+ * + * @settingDefault {@link CollectionClassification#BAG} + * + * @since 6.0 + * + * @see org.hibernate.annotations.Bag + */ + String DEFAULT_LIST_SEMANTICS = "hibernate.mapping.default_list_semantics"; + + /** + * Enable instantiation of composite/embedded objects when all attribute values + * are {@code null}. The default (and historical) behavior is that a {@code null} + * reference will be used to represent the composite value when all of its + * attributes are {@code null}. + * + * @apiNote This is an experimental feature that has known issues. It should not + * be used in production until it is stabilized. See Hibernate JIRA issue + * HHH-11936 for details. + * + * @deprecated It makes no sense at all to enable this at the global level for a + * persistence unit. If anything, it could be a setting specific to + * a given embeddable class. But, four years after the introduction of + * this feature, it's still marked experimental and has multiple known + * unresolved bugs. It's therefore time for those who advocated for + * this feature to accept defeat. + * + * @since 5.1 + */ + @Incubating + @Deprecated(since = "6") + String CREATE_EMPTY_COMPOSITES_ENABLED = "hibernate.create_empty_composites.enabled"; + + /** + * The {@link org.hibernate.annotations.Where @Where} annotation specifies a + * restriction on the table rows which are visible as entity class instances or + * collection elements. + *

+ * This setting controls whether the restriction applied to an entity should be + * applied to association fetches (for one-to-one, many-to-one, one-to-many, and + * many-to-many associations) which target the entity. + * + * @apiNote The setting is very misnamed - it applies across all entity associations, + * not only to collections. + * + * @implSpec Enabled ({@code true}) by default, meaning the restriction is applied. + * When this setting is explicitly disabled ({@code false}), the restriction + * is not applied. + * + * @deprecated Originally added as a backwards compatibility flag + */ + @Remove + @Deprecated( forRemoval = true, since = "6.2" ) + String USE_ENTITY_WHERE_CLAUSE_FOR_COLLECTIONS = "hibernate.use_entity_where_clause_for_collections"; + + /** + * Whether XML should be validated against their schema as Hibernate reads them. + * + * @settingDefault {@code true} + * + * @since 6.1 + */ + String VALIDATE_XML = "hibernate.validate_xml"; + + /** + * Enables processing {@code hbm.xml} mappings by transforming them to {@code mapping.xml} and using + * that processor. + * + * @settingDefault {@code false} (opt-in). + * + * @since 6.1 + */ + String TRANSFORM_HBM_XML = "hibernate.transform_hbm_xml.enabled"; + + /** + * How features in a {@code hbm.xml} file which are not supported for transformation + * should be handled. Valid values are defined by {@link UnsupportedFeatureHandling} + * + * @settingDefault {@link UnsupportedFeatureHandling#ERROR} + * + * @since 6.1 + */ + String TRANSFORM_HBM_XML_FEATURE_HANDLING = "hibernate.transform_hbm_xml.unsupported_feature_handling"; + + /** + * @see org.hibernate.boot.MetadataBuilder#enableImplicitForcingOfDiscriminatorsInSelect + * + * @settingDefault {@code false} + */ + String FORCE_DISCRIMINATOR_IN_SELECTS_BY_DEFAULT = "hibernate.discriminator.force_in_select"; + + /** + * Controls whether Hibernate should infer a discriminator for entity hierarchies + * defined with joined inheritance. + *

+ * Hibernate does not need a discriminator with joined inheritance. Therefore, its legacy + * behavior is to not infer a discriminator. However, some JPA providers do require + * discriminators with joined inheritance, so in the interest of portability this option + * has been added to Hibernate. When enabled ({@code true}), Hibernate will treat the absence + * of discriminator metadata as an indication to use the JPA defined defaults for discriminators. + * + * @implNote See Hibernate Jira issue HHH-6911 for additional background info. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.MetadataBuilder#enableImplicitDiscriminatorsForJoinedSubclassSupport + * @see #IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS + */ + String IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS = "hibernate.discriminator.implicit_for_joined"; + + /** + * Controls whether Hibernate should ignore explicit discriminator metadata with + * joined inheritance. + *

+ * Hibernate does not need a discriminator with joined inheritance. Historically + * it simply ignored discriminator metadata. When enabled ({@code true}), any + * discriminator metadata ({@link DiscriminatorColumn}, e.g.) is ignored allowing + * for backwards compatibility. + * + * @implNote See Hibernate Jira issue HHH-6911 for additional background info. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.MetadataBuilder#enableExplicitDiscriminatorsForJoinedSubclassSupport + * @see #IMPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS + */ + String IGNORE_EXPLICIT_DISCRIMINATOR_COLUMNS_FOR_JOINED_SUBCLASS = "hibernate.discriminator.ignore_explicit_for_joined"; + + /** + * By default, Hibernate maps character data represented by {@link String}s and + * {@link java.sql.Clob}s to the JDBC types {@link java.sql.Types#VARCHAR} and + * {@link java.sql.Types#CLOB}. This setting, when enabled, turns on the use of + * explicit nationalized character support for mappings involving character + * data, specifying that the JDBC types {@link java.sql.Types#NVARCHAR} and + * {@link java.sql.Types#NCLOB} should be used instead. + *

+ * This setting is relevant for use with databases with + * {@linkplain org.hibernate.dialect.NationalizationSupport#EXPLICIT explicit + * nationalization support}, and it is not needed for databases whose native + * {@code varchar} and {@code clob} types support Unicode data. (If you're not + * sure how your database handles Unicode, check out the implementation of + * {@link Dialect#getNationalizationSupport()} for its + * SQL dialect.) + *

+ * Enabling this setting has two effects: + *

    + *
  1. when interacting with JDBC, Hibernate uses operations like + * {@link java.sql.PreparedStatement#setNString(int, String)} + * {@link java.sql.PreparedStatement#setNClob(int, java.sql.NClob)} + * to pass character data, and + *
  2. when generating DDL, the schema export tool uses {@code nchar}, + * {@code nvarchar}, or {@code nclob} as the generated column + * type when no column type is explicitly specified using + * {@link jakarta.persistence.Column#columnDefinition()}. + *
+ * + * @apiNote This is a global setting applying to all mappings associated with a given + * {@link SessionFactory}. The {@link Nationalized} annotation may be used to + * selectively enable nationalized character support for specific columns. + * + * @settingDefault {@code false} (disabled) + * + * @see org.hibernate.boot.MetadataBuilder#enableGlobalNationalizedCharacterDataSupport(boolean) + * @see Dialect#getNationalizationSupport + * @see Nationalized + */ + String USE_NATIONALIZED_CHARACTER_DATA = "hibernate.use_nationalized_character_data"; + +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/MultiTenancySettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/MultiTenancySettings.java new file mode 100644 index 0000000000..619d1f3a27 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/MultiTenancySettings.java @@ -0,0 +1,47 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.context.spi.CurrentTenantIdentifierResolver; +import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; + +/** + * @author Steve Ebersole + */ +public interface MultiTenancySettings { + + /** + * Specifies a {@link MultiTenantConnectionProvider} + * to use. Since {@code MultiTenantConnectionProvider} is also a service, it may be configured + * directly via the {@link org.hibernate.boot.registry.StandardServiceRegistryBuilder}. + * + * @since 4.1 + */ + String MULTI_TENANT_CONNECTION_PROVIDER = "hibernate.multi_tenant_connection_provider"; + + /** + * Specifies a {@link CurrentTenantIdentifierResolver} to use, + * either: + *
    + *
  • an instance of {@code CurrentTenantIdentifierResolver}, + *
  • a {@link Class} representing an class that implements {@code CurrentTenantIdentifierResolver}, or + *
  • the name of a class that implements {@code CurrentTenantIdentifierResolver}. + *
+ * + * @see org.hibernate.boot.SessionFactoryBuilder#applyCurrentTenantIdentifierResolver(CurrentTenantIdentifierResolver) + * + * @since 4.1 + */ + String MULTI_TENANT_IDENTIFIER_RESOLVER = "hibernate.tenant_identifier_resolver"; + + /** + * During bootstrap, Hibernate needs access to any Connection for access to {@link java.sql.DatabaseMetaData}. + *

+ * This setting configures the name of the DataSource to use for this access + */ + String TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY = "hibernate.multi_tenant.datasource.identifier_for_any"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java new file mode 100644 index 0000000000..d93ffc5ab6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java @@ -0,0 +1,185 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.Incubating; +import org.hibernate.SessionFactoryObserver; + +import jakarta.persistence.spi.PersistenceUnitInfo; + +/** + * Settings related to persistence-units + * + * @author Steve Ebersole + */ +public interface PersistenceSettings { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Specifies a class implementing {@link jakarta.persistence.spi.PersistenceProvider}. + * Naturally, this should always be {@link org.hibernate.jpa.HibernatePersistenceProvider}, + * which is the best damn persistence provider ever. There's no need to explicitly specify + * this setting when there are no inferior persistence providers floating about. + *

+ * See JPA 2 sections 9.4.3 and 8.2.1.4 + */ + String JAKARTA_PERSISTENCE_PROVIDER = "jakarta.persistence.provider"; + + /** + * Specifies the {@linkplain jakarta.persistence.spi.PersistenceUnitTransactionType + * type of transactions} supported by the entity managers. The default depends on + * whether the program is considered to be executing in a Java SE or EE environment: + *

    + *
  • For Java SE, the default is + * {@link jakarta.persistence.spi.PersistenceUnitTransactionType#RESOURCE_LOCAL + * RESOURCE_LOCAL}. + *
  • For Java EE, the default is + * {@link jakarta.persistence.spi.PersistenceUnitTransactionType#JTA JTA}. + *
+ *

+ * See JPA 2 sections 9.4.3 and 8.2.1.2 + * + * @see PersistenceUnitInfo#getTransactionType() + */ + String JAKARTA_TRANSACTION_TYPE = "jakarta.persistence.transactionType"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Hibernate settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Setting used to name the Hibernate {@link org.hibernate.SessionFactory}. + *

+ * Naming the SessionFactory allows for it to be properly serialized across JVMs as + * long as the same name is used on each JVM. + *

+ * If {@link #SESSION_FACTORY_NAME_IS_JNDI} is set to {@code true}, this is also the + * name under which the SessionFactory is bound into JNDI on startup and from which + * it can be obtained from JNDI. + * + * @see #SESSION_FACTORY_NAME_IS_JNDI + * @see org.hibernate.internal.SessionFactoryRegistry + * @see org.hibernate.boot.SessionFactoryBuilder#applyName(String) + */ + String SESSION_FACTORY_NAME = "hibernate.session_factory_name"; + + /** + * Does the value defined by {@link #SESSION_FACTORY_NAME} represent a JNDI namespace + * into which the {@link org.hibernate.SessionFactory} should be bound and made accessible? + *

+ * Defaults to {@code true} for backwards compatibility. + *

+ * Set this to {@code false} if naming a SessionFactory is needed for serialization purposes, + * but no writable JNDI context exists in the runtime environment or if the user simply does + * not want JNDI to be used. + * + * @see #SESSION_FACTORY_NAME + * @see org.hibernate.boot.SessionFactoryBuilder#applyNameAsJndiName(boolean) + */ + String SESSION_FACTORY_NAME_IS_JNDI = "hibernate.session_factory_name_is_jndi"; + + /** + * Specifies the name of the persistence unit. + * + * @see PersistenceUnitInfo#getPersistenceUnitName() + */ + String PERSISTENCE_UNIT_NAME = "hibernate.persistenceUnitName"; + + /** + * Specifies an implementation of {@link org.hibernate.boot.archive.scan.spi.Scanner}, + * either: + *

    + *
  • an instance of {@code Scanner}, + *
  • a {@link Class} representing a class that implements {@code Scanner} + *
  • the name of a class that implements {@code Scanner}. + *
+ * + * @see org.hibernate.boot.MetadataBuilder#applyScanner + */ + String SCANNER = "hibernate.archive.scanner"; + + /** + * Specifies an {@link org.hibernate.boot.archive.spi.ArchiveDescriptorFactory} to use + * in the scanning process, either: + *
    + *
  • an instance of {@code ArchiveDescriptorFactory}, + *
  • a {@link Class} representing a class that implements {@code ArchiveDescriptorFactory}, or + *
  • the name of a class that implements {@code ArchiveDescriptorFactory}. + *
+ *

+ * See information on {@link org.hibernate.boot.archive.scan.spi.Scanner} + * about expected constructor forms. + * + * @see #SCANNER + * @see org.hibernate.boot.archive.scan.spi.Scanner + * @see org.hibernate.boot.archive.scan.spi.AbstractScannerImpl + * @see org.hibernate.boot.MetadataBuilder#applyArchiveDescriptorFactory + */ + String SCANNER_ARCHIVE_INTERPRETER = "hibernate.archive.interpreter"; + + /** + * Identifies a comma-separated list of values indicating the types of things we should + * auto-detect during scanning. Allowable values include: + *

    + *
  • {@code "class"} specifies that {@code .class} files are discovered as managed classes + *
  • {@code "hbm"} specifies that {@code hbm.xml} files are discovered as mapping files + *
+ * + * @see org.hibernate.boot.MetadataBuilder#applyScanOptions + */ + String SCANNER_DISCOVERY = "hibernate.archive.autodetection"; + + /** + * Allows JPA callbacks (via {@link jakarta.persistence.PreUpdate} and friends) to be + * completely disabled. Mostly useful to save some memory when they are not used. + *

+ * JPA callbacks are enabled by default. Set this property to {@code false} to disable + * them. + *

+ * Experimental and will likely be removed as soon as the memory overhead is resolved. + * + * @see org.hibernate.jpa.event.spi.CallbackType + * + * @since 5.4 + */ + @Incubating + String JPA_CALLBACKS_ENABLED = "hibernate.jpa_callbacks.enabled"; + + /** + * Specifies a class which implements {@link org.hibernate.SessionFactoryObserver} and has + * a constructor with no parameters. + * + * @see org.hibernate.boot.SessionFactoryBuilder#addSessionFactoryObservers(SessionFactoryObserver...) + */ + String SESSION_FACTORY_OBSERVER = "hibernate.session_factory_observer"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Legacy JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * @deprecated Use {@link #JAKARTA_PERSISTENCE_PROVIDER} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_PERSISTENCE_PROVIDER = "javax.persistence.provider"; + + /** + * The type of transactions supported by the entity managers. + *

+ * See JPA 2 sections 9.4.3 and 8.2.1.2 + * + * @deprecated Use {@link #JAKARTA_TRANSACTION_TYPE} instead + */ + @Deprecated + String JPA_TRANSACTION_TYPE = "javax.persistence.transactionType"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ProxoolSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/ProxoolSettings.java new file mode 100644 index 0000000000..5d4aeb36f3 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/ProxoolSettings.java @@ -0,0 +1,42 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +/** + * @author Steve Ebersole + */ +public interface ProxoolSettings { + + /** + * A setting prefix used to indicate settings that target the hibernate-proxool integration + */ + String PROXOOL_CONFIG_PREFIX = "hibernate.proxool"; + + /** + * Proxool property to configure the Proxool provider using an XML ({@code /path/to/file.xml}) + */ + String PROXOOL_XML = "hibernate.proxool.xml"; + + /** + * Proxool property to configure the Proxool provider using a properties file + * ({@code /path/to/proxool.properties}) + */ + String PROXOOL_PROPERTIES = "hibernate.proxool.properties"; + + /** + * Proxool property to configure the Proxool Provider from an already existing pool + * ({@code true} / {@code false}) + */ + String PROXOOL_EXISTING_POOL = "hibernate.proxool.existing_pool"; + + /** + * Proxool property with the Proxool pool alias to use + * (Required for {@link #PROXOOL_EXISTING_POOL}, {@link #PROXOOL_PROPERTIES}, or + * {@link #PROXOOL_XML}) + */ + String PROXOOL_POOL_ALIAS = "hibernate.proxool.pool_alias"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java new file mode 100644 index 0000000000..3151f7553e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java @@ -0,0 +1,225 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.query.NullPrecedence; +import org.hibernate.query.spi.QueryPlan; + +import jakarta.persistence.criteria.CriteriaDelete; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaUpdate; + +/** + * @author Steve Ebersole + */ +public interface QuerySettings { + /** + * Specifies a {@link org.hibernate.query.hql.HqlTranslator} to use for HQL query + * translation. + */ + String SEMANTIC_QUERY_PRODUCER = "hibernate.query.hql.translator"; + + /** + * Specifies a {@link org.hibernate.query.sqm.sql.SqmTranslatorFactory} to use for + * HQL query translation. + */ + String SEMANTIC_QUERY_TRANSLATOR = "hibernate.query.sqm.translator"; + + /** + * Defines the "global" strategy to use for handling HQL and Criteria mutation queries. + * Specifies a {@link org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy}.. + */ + String QUERY_MULTI_TABLE_MUTATION_STRATEGY = "hibernate.query.mutation_strategy"; + + /** + * Defines the "global" strategy to use for handling HQL and Criteria insert queries. + * Specifies a {@link org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy}. + */ + String QUERY_MULTI_TABLE_INSERT_STRATEGY = "hibernate.query.insert_strategy"; + + /** + * When enabled, specifies that named queries be checked during startup. + *

+ * By default, named queries are checked at startup. + *

+ * Mainly intended for use in test environments. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyNamedQueryCheckingOnStartup(boolean) + */ + String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check"; + + /** + * By default, a {@linkplain jakarta.persistence.criteria.CriteriaBuilder criteria + * query} produces SQL with a JDBC bind parameter for any value specified via the + * criteria query API, except when the value is passed via + * {@link jakarta.persistence.criteria.CriteriaBuilder#literal(Object)}, in which + * case the value is "inlined" as a SQL literal. + *

+ * This setting may be used to override this default behavior: + *

    + *
  • the {@link org.hibernate.query.criteria.ValueHandlingMode#BIND "bind"} + * mode uses bind parameters to pass such values to JDBC, but + *
  • the {@link org.hibernate.query.criteria.ValueHandlingMode#INLINE "inline"} + * mode inlines values as SQL literals. + *
+ *

+ * In both modes: + *

    + *
  • values specified using {@code literal()} are inlined, and + *
  • values specified using + * {@link jakarta.persistence.criteria.CriteriaBuilder#parameter(Class)} to create a + * {@link jakarta.persistence.criteria.ParameterExpression criteria parameter} and + * {@link jakarta.persistence.Query#setParameter(jakarta.persistence.Parameter,Object)} + * to specify its argument are passed to JDBC using a bind parameter. + *
+ *

+ * The default mode is {@link org.hibernate.query.criteria.ValueHandlingMode#BIND}. + * + * @since 6.0.0 + * + * @see org.hibernate.query.criteria.ValueHandlingMode + * @see jakarta.persistence.criteria.CriteriaBuilder#literal(Object) + * @see jakarta.persistence.criteria.CriteriaBuilder#parameter(Class) + * @see org.hibernate.query.criteria.HibernateCriteriaBuilder#value(Object) + */ + String CRITERIA_VALUE_HANDLING_MODE = "hibernate.criteria.value_handling_mode"; + + /** + * Specifies the default {@linkplain NullPrecedence precedence of null values} in the HQL + * {@code ORDER BY} clause, either {@code none}, {@code first}, or {@code last}. + *

+ * The default is {@code none}. + * + * @see NullPrecedence + * @see org.hibernate.boot.SessionFactoryBuilder#applyDefaultNullPrecedence(NullPrecedence) + */ + String DEFAULT_NULL_ORDERING = "hibernate.order_by.default_null_ordering"; + + /** + * When enabled, specifies that {@linkplain org.hibernate.query.Query queries} + * created via {@link jakarta.persistence.EntityManager#createQuery(CriteriaQuery)}, + * {@link jakarta.persistence.EntityManager#createQuery(CriteriaUpdate)} or + * {@link jakarta.persistence.EntityManager#createQuery(CriteriaDelete)} must + * create a copy of the passed criteria query object such that the resulting + * {@link jakarta.persistence.Query} object is not affected by mutation of the + * original {@linkplain CriteriaQuery criteria query}. + *

+ * If disabled, it's assumed that the client does not mutate the criteria query + * after calling {@code createQuery()}. Thus, in the interest of performance, no + * copy is created. + *

+ * The default behavior depends on how Hibernate is bootstrapped: + *

    + *
  • When bootstrapping Hibernate through the native bootstrap APIs, this setting + * is disabled, that is, no copy of the criteria query object is made. + *
  • When bootstrapping Hibernate through the JPA SPI, this setting is enabled so + * that criteria query objects are copied, as required by the JPA specification. + *
+ * + * @since 6.0 + */ + String CRITERIA_COPY_TREE = "hibernate.criteria.copy_tree"; + + /** + * When {@linkplain org.hibernate.query.Query#setMaxResults(int) pagination} is used + * in combination with a {@code fetch join} applied to a collection or many-valued + * association, the limit must be applied in-memory instead of on the database. This + * typically has terrible performance characteristics, and should be avoided. + *

+ * When enabled, this setting specifies that an exception should be thrown for any + * query which would result in the limit being applied in-memory. + *

+ * By default, the exception is disabled, and the possibility of terrible + * performance is left as a problem for the client to avoid. + * + * @since 5.2.13 + */ + String FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH = "hibernate.query.fail_on_pagination_over_collection_fetch"; + + /** + * This setting defines how {@link org.hibernate.annotations.Immutable} entities + * are handled when executing a bulk update query. Valid options are enumerated + * by {@link org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode}: + *

    + *
  • {@link org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode#WARNING "warning"} + * specifies that a warning log message is issued when an + * {@linkplain org.hibernate.annotations.Immutable immutable} entity is to be + * updated via a bulk update statement, and + *
  • {@link org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode#EXCEPTION "exception"} + * specifies that a {@link org.hibernate.HibernateException} should be thrown. + *
+ *

+ * By default, a warning is logged. + * + * @since 5.2.17 + * + * @see org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode + */ + String IMMUTABLE_ENTITY_UPDATE_QUERY_HANDLING_MODE = "hibernate.query.immutable_entity_update_query_handling_mode"; + + /** + * Determines how parameters occurring in a SQL {@code IN} predicate are expanded. + * By default, the {@code IN} predicate expands to include sufficient bind parameters + * to accommodate the specified arguments. + *

+ * However, for database systems supporting execution plan caching, there's a + * better chance of hitting the cache if the number of possible {@code IN} clause + * parameter list lengths is smaller. + *

+ * When this setting is enabled, we expand the number of bind parameters to an + * integer power of two: 4, 8, 16, 32, 64. Thus, if 5, 6, or 7 arguments are bound + * to a parameter, a SQL statement with 8 bind parameters in the {@code IN} clause + * will be used, and null will be bound to the left-over parameters. + * + * @since 5.2.17 + */ + String IN_CLAUSE_PARAMETER_PADDING = "hibernate.query.in_clause_parameter_padding"; + + /** + * When enabled, specifies that Hibernate should attempt to map parameter names + * given in a {@link org.hibernate.procedure.ProcedureCall} or + * {@link jakarta.persistence.StoredProcedureQuery} to named parameters of the + * JDBC {@link java.sql.CallableStatement}. + * + * @see org.hibernate.boot.spi.SessionFactoryOptions#isUseOfJdbcNamedParametersEnabled() + * + * @since 6.0 + */ + String CALLABLE_NAMED_PARAMS_ENABLED = "hibernate.query.proc.callable_named_params_enabled"; + + /** + * When enabled, specifies that {@linkplain QueryPlan query plans} should be + * {@linkplain org.hibernate.query.spi.QueryInterpretationCache cached}. + *

+ * By default, the query plan cache is disabled, unless one of the configuration + * properties {@value #QUERY_PLAN_CACHE_MAX_SIZE} or + * {@value #QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE} is set. + */ + String QUERY_PLAN_CACHE_ENABLED = "hibernate.query.plan_cache_enabled"; + + /** + * The maximum number of entries in the + * {@linkplain org.hibernate.query.spi.QueryInterpretationCache + * query interpretation cache}. + *

+ * The default maximum is + * {@value org.hibernate.query.spi.QueryEngine#DEFAULT_QUERY_PLAN_MAX_COUNT}. + * + * @see org.hibernate.query.spi.QueryInterpretationCache + */ + String QUERY_PLAN_CACHE_MAX_SIZE = "hibernate.query.plan_cache_max_size"; + + /** + * The maximum number of {@link org.hibernate.query.ParameterMetadata} instances + * maintained by the {@link org.hibernate.query.spi.QueryInterpretationCache}. + *

+ * + * @deprecated this setting is not currently used + */ + @Deprecated(since="6.0") + String QUERY_PLAN_CACHE_PARAMETER_METADATA_MAX_SIZE = "hibernate.query.plan_parameter_metadata_max_size"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/SchemaToolingSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/SchemaToolingSettings.java new file mode 100644 index 0000000000..f91b761db9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/SchemaToolingSettings.java @@ -0,0 +1,468 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableStrategy; +import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableStrategy; +import org.hibernate.query.sqm.mutation.internal.temptable.PersistentTableStrategy; +import org.hibernate.tool.schema.UniqueConstraintSchemaUpdateStrategy; + +/** + * @author Steve Ebersole + */ +public interface SchemaToolingSettings { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Specifies what type of schema tooling action should be performed against the + * database specified using either {@value JdbcSettings#JAKARTA_HBM2DDL_CONNECTION} or the + * configured {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} + * for the {@link org.hibernate.SessionFactory}. + *

+ * Valid options are enumerated by {@link org.hibernate.tool.schema.Action}. + *

+ * This setting takes precedence over {@value #HBM2DDL_AUTO}. + *

+ * If no value is specified, the default is + * {@link org.hibernate.tool.schema.Action#NONE "none"}. + * + * @see org.hibernate.tool.schema.Action + * @see JdbcSettings#JAKARTA_HBM2DDL_CONNECTION + * @see JdbcSettings#JAKARTA_JDBC_URL + */ + String JAKARTA_HBM2DDL_DATABASE_ACTION = "jakarta.persistence.schema-generation.database.action"; + + /** + * Specifies what type of schema tooling action should be written to script files. + *

+ * Valid options are enumerated by {@link org.hibernate.tool.schema.Action}. + *

+ * The script file is identified using {@value #JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET}. + *

+ * If no value is specified, the default is + * {@link org.hibernate.tool.schema.Action#NONE "none"}. + * + * @see org.hibernate.tool.schema.Action + * @see #JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET + * @see #JAKARTA_HBM2DDL_SCRIPTS_DROP_TARGET + */ + String JAKARTA_HBM2DDL_SCRIPTS_ACTION = "jakarta.persistence.schema-generation.scripts.action"; + + /** + * Specifies whether schema generation commands for schema creation are to be determined + * based on object/relational mapping metadata, DDL scripts, or a combination of the two. + * See {@link org.hibernate.tool.schema.SourceType} for the list of legal values. + *

+ * If no value is specified, a default is inferred as follows: + *

    + *
  • if source scripts are specified via {@value #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE}, + * then {@link org.hibernate.tool.schema.SourceType#SCRIPT "script"} is assumed, or + *
  • otherwise, {@link org.hibernate.tool.schema.SourceType#SCRIPT "metadata"} is + * assumed. + *
+ * + * @see org.hibernate.tool.schema.SourceType + */ + String JAKARTA_HBM2DDL_CREATE_SOURCE = "jakarta.persistence.schema-generation.create-source"; + + /** + * Specifies whether schema generation commands for schema dropping are to be determined + * based on object/relational mapping metadata, DDL scripts, or a combination of the two. + * See {@link org.hibernate.tool.schema.SourceType} for the list of legal values. + *

+ * If no value is specified, a default is inferred as follows: + *

    + *
  • if source scripts are specified via {@value #JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE}, + * then {@linkplain org.hibernate.tool.schema.SourceType#SCRIPT "script"} is assumed, or + *
  • otherwise, {@linkplain org.hibernate.tool.schema.SourceType#SCRIPT "metadata"} + * is assumed. + *
+ * + * @see org.hibernate.tool.schema.SourceType + */ + String JAKARTA_HBM2DDL_DROP_SOURCE = "jakarta.persistence.schema-generation.drop-source"; + + /** + * Specifies the CREATE script file as either a {@link java.io.Reader} configured for reading + * the DDL script file or a string designating a file {@link java.net.URL} for the DDL script. + *

+ * Hibernate historically also accepted {@link #HBM2DDL_IMPORT_FILES} for a similar purpose. + * This setting is now preferred. + * + * @see #JAKARTA_HBM2DDL_CREATE_SOURCE + * @see #HBM2DDL_IMPORT_FILES + */ + String JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE = "jakarta.persistence.schema-generation.create-script-source"; + + /** + * Specifies the DROP script file as either a {@link java.io.Reader} configured for reading + * the DDL script file or a string designating a file {@link java.net.URL} for the DDL script. + * + * @see #JAKARTA_HBM2DDL_DROP_SOURCE + */ + String JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE = "jakarta.persistence.schema-generation.drop-script-source"; + + /** + * For cases where {@value #JAKARTA_HBM2DDL_SCRIPTS_ACTION} indicates that schema creation + * commands should be written to a script file, this setting specifies either a + * {@link java.io.Writer} configured for output of the DDL script or a string specifying + * the file URL for the DDL script. + * + * @see #JAKARTA_HBM2DDL_SCRIPTS_ACTION + */ + String JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET = "jakarta.persistence.schema-generation.scripts.create-target"; + + /** + * For cases where {@value #JAKARTA_HBM2DDL_SCRIPTS_ACTION} indicates that schema + * drop commands should be written to a script file, this setting specifies either a + * {@link java.io.Writer} configured for output of the DDL script or a string + * specifying the file URL for the DDL script. + * + * @see #JAKARTA_HBM2DDL_SCRIPTS_ACTION + */ + String JAKARTA_HBM2DDL_SCRIPTS_DROP_TARGET = "jakarta.persistence.schema-generation.scripts.drop-target"; + + /** + * JPA-standard variant of {@link #HBM2DDL_IMPORT_FILES} for specifying a database + * initialization script to be run as part of schema-export + *

+ * Specifies a {@link java.io.Reader} configured for reading of the SQL load script + * or a string designating the {@link java.net.URL} for the SQL load script. + */ + String JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE = "jakarta.persistence.sql-load-script-source"; + + /** + * The JPA variant of {@link #HBM2DDL_CREATE_NAMESPACES} used to specify whether database + * schemas used in the mapping model should be created on export in addition to creating + * the tables, sequences, etc. + *

+ * The default is {@code false}, meaning to not create schemas + */ + String JAKARTA_HBM2DDL_CREATE_SCHEMAS = "jakarta.persistence.create-database-schemas"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Hibernate settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Specifies the {@link org.hibernate.tool.schema.spi.SchemaManagementTool} to use for + * performing schema management. + *

+ * By default, {@link org.hibernate.tool.schema.internal.HibernateSchemaManagementTool} + * is used. + * + * @since 5.0 + */ + String SCHEMA_MANAGEMENT_TOOL = "hibernate.schema_management_tool"; + + /** + * Setting to perform {@link org.hibernate.tool.schema.spi.SchemaManagementTool} + * actions automatically as part of the {@link org.hibernate.SessionFactory} + * lifecycle. Valid options are enumerated by {@link org.hibernate.tool.schema.Action}. + *

+ * Interpreted in combination with {@link #JAKARTA_HBM2DDL_DATABASE_ACTION} and + * {@link #JAKARTA_HBM2DDL_SCRIPTS_ACTION}. If no value is specified, the default + * is {@linkplain org.hibernate.tool.schema.Action#NONE "none"}. + * + * @settingDefault {@code "none"} + * + * @see org.hibernate.tool.schema.Action + */ + String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto"; + + /** + * For cases where the {@value #JAKARTA_HBM2DDL_SCRIPTS_ACTION} value indicates that schema commands + * should be written to DDL script file, specifies if schema commands should be appended to + * the end of the file rather than written at the beginning of the file. + *

+ * Values are: {@code true} for appending schema commands to the end of the file, {@code false} + * for writing schema commands at the beginning. + * + * @settingDefault {@code true} + */ + String HBM2DDL_SCRIPTS_CREATE_APPEND = "hibernate.hbm2ddl.schema-generation.script.append"; + + /** + * The {@link org.hibernate.tool.schema.spi.SqlScriptCommandExtractor} implementation + * to use for parsing source/import files specified by {@link #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE}, + * {@link #JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE} or {@link #HBM2DDL_IMPORT_FILES}. Either: + *

    + *
  • an instance of {@link org.hibernate.tool.schema.spi.SqlScriptCommandExtractor}, + *
  • a {@link Class} object representing a class that implements {@code SqlScriptCommandExtractor}, + * or + *
  • the name of a class that implements {@code SqlScriptCommandExtractor}. + *
+ *

+ * The correct extractor to use depends on the format of the SQL script: + *

    + *
  • if the script has one complete SQL statement per line, use + * {@link org.hibernate.tool.schema.internal.script.SingleLineSqlScriptExtractor}, or + *
  • if a script contains statements spread over multiple lines, use + * {@link org.hibernate.tool.schema.internal.script.MultiLineSqlScriptExtractor}. + *
+ * + * @settingDefault {@code org.hibernate.tool.schema.internal.script.SingleLineSqlScriptExtractor}. + * + * @see org.hibernate.tool.schema.internal.script.SingleLineSqlScriptExtractor + * @see org.hibernate.tool.schema.internal.script.MultiLineSqlScriptExtractor + */ + String HBM2DDL_IMPORT_FILES_SQL_EXTRACTOR = "hibernate.hbm2ddl.import_files_sql_extractor"; + + /** + * Used to specify the {@link org.hibernate.tool.schema.spi.SchemaFilterProvider} to be + * used by create, drop, migrate and validate operations on the database schema. A + * {@code SchemaFilterProvider} provides filters that can be used to limit the scope of + * these operations to specific namespaces, tables and sequences. All objects are + * included by default. + * + * @since 5.1 + */ + String HBM2DDL_FILTER_PROVIDER = "hibernate.hbm2ddl.schema_filter_provider"; + + /** + * Setting to choose the strategy used to access the JDBC Metadata. + *

+ * Valid options are defined by {@link org.hibernate.tool.schema.JdbcMetadaAccessStrategy}. + * {@link org.hibernate.tool.schema.JdbcMetadaAccessStrategy#GROUPED} is the default. + * + * @settingDefault Grouped, unless {@value #ENABLE_SYNONYMS} is enabled + * + * @see org.hibernate.tool.schema.JdbcMetadaAccessStrategy + */ + String HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY = "hibernate.hbm2ddl.jdbc_metadata_extraction_strategy"; + + /** + * Identifies the delimiter to use to separate schema management statements in script + * outputs. + * + * @settingDefault {@code ;} + */ + String HBM2DDL_DELIMITER = "hibernate.hbm2ddl.delimiter"; + + /** + * The name of the charset used by the schema generation resource. + *

+ * By default, the JVM default charset is used. + * + * @since 5.2.3 + */ + String HBM2DDL_CHARSET_NAME = "hibernate.hbm2ddl.charset_name"; + + /** + * When enabled, specifies that the schema migration tool should halt on any error, + * terminating the bootstrap process. + * + * @settingDefault {@code false} + * + * @since 5.2.4 + */ + String HBM2DDL_HALT_ON_ERROR = "hibernate.hbm2ddl.halt_on_error"; + + /** + * Used with the {@link jakarta.persistence.ConstraintMode#PROVIDER_DEFAULT} + * strategy for foreign key mapping. + *

+ * Valid values are {@link jakarta.persistence.ConstraintMode#CONSTRAINT} and + * {@link jakarta.persistence.ConstraintMode#NO_CONSTRAINT}. + * + * @settingDefault {@link jakarta.persistence.ConstraintMode#CONSTRAINT}. + * + * @since 5.4 + */ + String HBM2DDL_DEFAULT_CONSTRAINT_MODE = "hibernate.hbm2ddl.default_constraint_mode"; + + /** + * Specifies the default storage engine for a relational databases that supports + * multiple storage engines. This property must be set either as an {@link Environment} + * variable or JVM System Property, since the {@link org.hibernate.dialect.Dialect} is + * instantiated before Hibernate property resolution. + * + * @since 5.2.9 + */ + String STORAGE_ENGINE = "hibernate.dialect.storage_engine"; + + /** + * If enabled, allows schema update and validation to support synonyms. Due + * to the possibility that this would return duplicate tables (especially in + * Oracle), this is disabled by default. + * + * @settingDefault {@code false} + */ + String ENABLE_SYNONYMS = "hibernate.synonyms"; + + /** + * Specifies a comma-separated list of extra table types, in addition to the + * default types {@code "TABLE"} and {@code "VIEW"}, to recognize as physical + * tables when performing schema update, creation and validation. + * + * @since 5.0 + */ + String EXTRA_PHYSICAL_TABLE_TYPES = "hibernate.hbm2ddl.extra_physical_table_types"; + + /** + * Unique columns and unique keys both use unique constraints in most dialects. + * The schema exporter must create these constraints, but database support for + * finding existing constraints is extremely inconsistent. Worse, unique constraints + * without explicit names are assigned names with randomly generated characters. + *

+ * Therefore, select from these strategies: + *

    + *
  • {@linkplain UniqueConstraintSchemaUpdateStrategy#DROP_RECREATE_QUIETLY DROP_RECREATE_QUIETLY}: + * Attempt to drop, then (re-)create each unique constraint, ignoring any exceptions thrown. + * This is the default. + *
  • {@linkplain UniqueConstraintSchemaUpdateStrategy#RECREATE_QUIETLY RECREATE_QUIETLY}: + * Attempt to (re-)create unique constraints, ignoring exceptions thrown if the constraint already existed. + *
  • {@linkplain UniqueConstraintSchemaUpdateStrategy#SKIP SKIP}: + * Do not attempt to create unique constraints on a schema update. + *
+ * + * @settingDefault {@linkplain UniqueConstraintSchemaUpdateStrategy#DROP_RECREATE_QUIETLY DROP_RECREATE_QUIETLY} + */ + String UNIQUE_CONSTRAINT_SCHEMA_UPDATE_STRATEGY = "hibernate.schema_update.unique_constraint_strategy"; + + /** + * Allows creation of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#PERSISTENT persistent} + * temporary tables at application startup to be disabled. By default, table creation is enabled. + */ + String BULK_ID_STRATEGY_PERSISTENT_TEMPORARY_CREATE_TABLES = PersistentTableStrategy.CREATE_ID_TABLES; + + /** + * Allows dropping of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#PERSISTENT persistent} + * temporary tables at application shutdown to be disabled. By default, table dropping is enabled. + */ + String BULK_ID_STRATEGY_PERSISTENT_TEMPORARY_DROP_TABLES = PersistentTableStrategy.DROP_ID_TABLES; + + /** + * Allows creation of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#GLOBAL global} + * temporary tables at application startup to be disabled. By default, table creation is enabled. + */ + String BULK_ID_STRATEGY_GLOBAL_TEMPORARY_CREATE_TABLES = GlobalTemporaryTableStrategy.CREATE_ID_TABLES; + + /** + * Allows dropping of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#GLOBAL global} + * temporary tables at application shutdown to be disabled. By default, table dropping is enabled. + */ + String BULK_ID_STRATEGY_GLOBAL_TEMPORARY_DROP_TABLES = GlobalTemporaryTableStrategy.DROP_ID_TABLES; + + /** + * Allows dropping of {@linkplain org.hibernate.dialect.temptable.TemporaryTableKind#LOCAL local} + * temporary tables at transaction commit to be enabled. By default, table dropping is disabled, + * and the database will drop the temporary tables automatically. + */ + String BULK_ID_STRATEGY_LOCAL_TEMPORARY_DROP_TABLES = LocalTemporaryTableStrategy.DROP_ID_TABLES; + + + + /** + * Specifies a comma-separated list of file names of scripts containing SQL DML statements that + * should be executed after schema export completes. The order of the scripts is significant, + * with the first script in the list being executed first. + *

+ * The scripts are only executed if the schema is created by Hibernate, that is, if + * {@value #HBM2DDL_AUTO} is set to {@code create} or {@code create-drop}. + *

+ * The default value is {@code /import.sql}. + * + * @deprecated The JPA-standard setting {@link #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE} is now preferred. + */ + @Deprecated + String HBM2DDL_IMPORT_FILES = "hibernate.hbm2ddl.import_files"; + + /** + * Specifies whether to automatically create also the database schema/catalog. + * The default is false. + * + * @since 5.0 + * + * @deprecated The JPA-standard setting {@link #JAKARTA_HBM2DDL_CREATE_SCHEMAS} is now preferred. + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_CREATE_NAMESPACES = "hibernate.hbm2ddl.create_namespaces"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Legacy JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * @deprecated Use {@link #JAKARTA_HBM2DDL_DATABASE_ACTION} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_DATABASE_ACTION = "javax.persistence.schema-generation.database.action"; + + /** + * @deprecated Use {@link #JAKARTA_HBM2DDL_SCRIPTS_ACTION} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_SCRIPTS_ACTION = "javax.persistence.schema-generation.scripts.action"; + + /** + * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_CREATE_SOURCE} instead + * @see org.hibernate.tool.schema.SourceType + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_CREATE_SOURCE = "javax.persistence.schema-generation.create-source"; + + /** + * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_DROP_SOURCE}. + * @see org.hibernate.tool.schema.SourceType + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_DROP_SOURCE = "javax.persistence.schema-generation.drop-source"; + + /** + * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_CREATE_SCRIPT_SOURCE} + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_CREATE_SCRIPT_SOURCE = "javax.persistence.schema-generation.create-script-source"; + + /** + * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_DROP_SCRIPT_SOURCE} + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_DROP_SCRIPT_SOURCE = "javax.persistence.schema-generation.drop-script-source"; + + /** + * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET} + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_SCRIPTS_CREATE_TARGET = "javax.persistence.schema-generation.scripts.create-target"; + + + /** + * @deprecated Migrate to {@link #JAKARTA_HBM2DDL_SCRIPTS_DROP_TARGET} + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_SCRIPTS_DROP_TARGET = "javax.persistence.schema-generation.scripts.drop-target"; + + /** + * @deprecated Use {@link #JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_LOAD_SCRIPT_SOURCE = "javax.persistence.sql-load-script-source"; + + /** + * @deprecated Use {@link #JAKARTA_HBM2DDL_CREATE_SCHEMAS} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String HBM2DDL_CREATE_SCHEMAS = "javax.persistence.create-database-schemas"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/SessionEventSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/SessionEventSettings.java new file mode 100644 index 0000000000..5dfeb935b2 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/SessionEventSettings.java @@ -0,0 +1,80 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import java.util.function.Supplier; + +import org.hibernate.Interceptor; + +/** + * @author Steve Ebersole + */ +public interface SessionEventSettings { + + /** + * Controls whether {@linkplain org.hibernate.stat.SessionStatistics session metrics} + * should be {@linkplain org.hibernate.engine.internal.StatisticalLoggingSessionEventListener + * logged} for any session in which statistics are being collected. + *

+ * By default, logging of session metrics is disabled unless {@link StatisticsSettings#GENERATE_STATISTICS} + * is enabled. + * + * @settingDefault Defined by {@link StatisticsSettings#GENERATE_STATISTICS} + */ + String LOG_SESSION_METRICS = "hibernate.session.events.log"; + + /** + * Defines a default {@link org.hibernate.SessionEventListener} to be applied to + * newly-opened {@link org.hibernate.Session}s. + */ + String AUTO_SESSION_EVENTS_LISTENER = "hibernate.session.events.auto"; + + /** + * Specifies an {@link org.hibernate.Interceptor} implementation associated with + * the {@link org.hibernate.SessionFactory} and propagated to each {@code Session} + * created from the {@code SessionFactory}. Either: + *

    + *
  • an instance of {@code Interceptor}, + *
  • a {@link Class} representing a class that implements {@code Interceptor}, or + *
  • the name of a class that implements {@code Interceptor}. + *
+ *

+ * This setting identifies an {@code Interceptor} which is effectively a singleton + * across all the sessions opened from the {@code SessionFactory} to which it is + * applied; the same instance will be passed to each {@code Session}. If there + * should be a separate instance of {@code Interceptor} for each {@code Session}, + * use {@link #SESSION_SCOPED_INTERCEPTOR} instead. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyInterceptor(Interceptor) + * + * @since 5.0 + */ + String INTERCEPTOR = "hibernate.session_factory.interceptor"; + + /** + * Specifies an {@link org.hibernate.Interceptor} implementation associated with + * the {@link org.hibernate.SessionFactory} and propagated to each {@code Session} + * created from the {@code SessionFactory}. Either: + *

    + *
  • a {@link Class} representing a class that implements {@code Interceptor}, + *
  • the name of a class that implements {@code Interceptor}, or + *
  • an instance of {@link Supplier} used to obtain the interceptor. + *
+ *

+ * Note that this setting cannot specify an {@code Interceptor} instance. + *

+ * This setting identifies an {@code Interceptor} implementation that is to be + * applied to every {@code Session} opened from the {@code SessionFactory}, but + * unlike {@link #INTERCEPTOR}, a separate instance created for each {@code Session}. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyStatelessInterceptor(Class) + * @see org.hibernate.boot.SessionFactoryBuilder#applyStatelessInterceptor(Supplier) + * + * @since 5.2 + */ + String SESSION_SCOPED_INTERCEPTOR = "hibernate.session_factory.session_scoped_interceptor"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/StatisticsSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/StatisticsSettings.java new file mode 100644 index 0000000000..13cf0f9d12 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/StatisticsSettings.java @@ -0,0 +1,46 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import org.hibernate.stat.spi.StatisticsFactory; + +/** + * @author Steve Ebersole + */ +public interface StatisticsSettings { + /** + * When enabled, specifies that {@linkplain org.hibernate.stat.Statistics statistics} + * should be collected. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyStatisticsSupport(boolean) + */ + String GENERATE_STATISTICS = "hibernate.generate_statistics"; + + /** + * When statistics are {@linkplain #GENERATE_STATISTICS enabled}, names the + * {@link StatisticsFactory} to use. Recognizes a class name as well as an instance of + * {@link StatisticsFactory}. + *

+ * Allows customization of how the Hibernate Statistics are collected. + */ + String STATS_BUILDER = "hibernate.stats.factory"; + + /** + * This setting controls the number of {@link org.hibernate.stat.QueryStatistics} + * entries that will be stored by the Hibernate {@link org.hibernate.stat.Statistics} + * object. + *

+ * The default value is {@value org.hibernate.stat.Statistics#DEFAULT_QUERY_STATISTICS_MAX_SIZE}. + * + * @since 5.4 + * + * @see org.hibernate.stat.Statistics#getQueries() + */ + String QUERY_STATISTICS_MAX_SIZE = "hibernate.statistics.query_max_size"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/TransactionSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/TransactionSettings.java new file mode 100644 index 0000000000..94d284499b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/TransactionSettings.java @@ -0,0 +1,181 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +import jakarta.persistence.spi.PersistenceUnitInfo; + +/** + * @author Steve Ebersole + */ +public interface TransactionSettings { + /** + * Specify the {@link org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder} + * implementation to use for creating instances of + * {@link org.hibernate.resource.transaction.spi.TransactionCoordinator} which the interface + * Hibernate uses to manage transactions. + *

+ * Accepts either: + *

    + *
  • an instance of {@code TransactionCoordinatorBuilder}, + *
  • a {@link Class} representing a class that implements {@code TransactionCoordinatorBuilder}, + *
  • the name of a class that implements {@code TransactionCoordinatorBuilder}, + *
  • {@code jta} or {@code jdbc}
  • + *
+ *

+ * + * @settingDefault With Jakarta Persistence bootstrapping, based on the persistence unit's {@link PersistenceUnitInfo#getTransactionType()}; + * otherwise {@code jdbc}. + * + * @implSpec With non Jakarta Persistence bootstrapping, Hibernate will use {@code jdbc} as the default which + * will cause problems if the application actually uses JTA-based transactions. + * + * @see #JTA_PLATFORM + * + * @since 5.0 + */ + String TRANSACTION_COORDINATOR_STRATEGY = "hibernate.transaction.coordinator_class"; + + /** + * Specifies the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform} + * implementation to use for integrating with JTA, either: + *

    + *
  • an instance of {@code JtaPlatform}, or + *
  • the name of a class that implements {@code JtaPlatform}. + *
  • short name of a class (sans package name) that implements {@code JtaPlatform}. + *
+ * + * @see #JTA_PLATFORM_RESOLVER + * + * @since 4.0 + */ + String JTA_PLATFORM = "hibernate.transaction.jta.platform"; + + /** + * Specifies a {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformResolver} + * implementation that should be used to obtain an instance of + * {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform}. + * + * @since 4.3 + */ + String JTA_PLATFORM_RESOLVER = "hibernate.transaction.jta.platform_resolver"; + + /** + * When enabled, specifies that the {@link jakarta.transaction.UserTransaction} should + * be used in preference to the {@link jakarta.transaction.TransactionManager} for JTA + * transaction management. + *

+ * By default, the {@code TransactionManager} is preferred. + * + * @see org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform#retrieveUserTransaction + * @see org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform#retrieveTransactionManager + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyPreferUserTransactions(boolean) + * + * @settingDefault {@code false} as {@code TransactionManager} is preferred. + * + * @since 5.0 + */ + String PREFER_USER_TRANSACTION = "hibernate.jta.prefer_user_transaction"; + + /** + * When enabled, indicates that it is safe to cache {@link jakarta.transaction.TransactionManager} + * references in the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform} + * + * @settingDefault Generally {@code true}, though {@code JtaPlatform} implementations + * can do their own thing. + * + * @since 4.0 + */ + String JTA_CACHE_TM = "hibernate.jta.cacheTransactionManager"; + + /** + * When enabled, indicates that it is safe to cache {@link jakarta.transaction.UserTransaction} + * references in the {@link org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform} + * + * @settingDefault Generally {@code true}, though {@code JtaPlatform} implementations + * can do their own thing. + * + * @since 4.0 + */ + String JTA_CACHE_UT = "hibernate.jta.cacheUserTransaction"; + + /** + * A transaction can be rolled back by another thread ("tracking by thread") + * -- not the original application. Examples of this include a JTA + * transaction timeout handled by a background reaper thread. The ability + * to handle this situation requires checking the Thread ID every time + * Session is called. This can certainly have performance considerations. + * + * @settingDefault {@code true} (enabled). + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyJtaTrackingByThread(boolean) + */ + String JTA_TRACK_BY_THREAD = "hibernate.jta.track_by_thread"; + + /** + * When enabled, allows access to the {@link org.hibernate.Transaction} even when + * using a JTA for transaction management. + *

+ * Values are {@code true}, which grants access, and {@code false}, which does not. + *

+ * + * @settingDefault {@code false} when bootstrapped via JPA; {@code true} otherwise. + * + * @see JpaComplianceSettings#JPA_TRANSACTION_COMPLIANCE + */ + String ALLOW_JTA_TRANSACTION_ACCESS = "hibernate.jta.allowTransactionAccess"; + + /** + * Allows a detached proxy or lazy collection to be fetched even when not + * associated with an open persistence context, by creating a temporary + * persistence context when the proxy or collection is accessed. This + * behavior is not recommended, since it can easily break transaction + * isolation or lead to data aliasing; it is therefore disabled by default. + * + * @settingDefault {@code false} (disabled) + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyLazyInitializationOutsideTransaction(boolean) + */ + String ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans"; + + /** + * When enabled, allows update operations outside a transaction. + *

+ * Since version 5.2 Hibernate conforms with the JPA specification and disallows + * flushing any update outside a transaction. + *

+ * Values are {@code true}, which allows flushing outside a transaction, and + * {@code false}, which does not. + *

+ * The default behavior is to disallow update operations outside a transaction. + * + * @see org.hibernate.boot.SessionFactoryBuilder#allowOutOfTransactionUpdateOperations(boolean) + * + * @since 5.2 + */ + String ALLOW_UPDATE_OUTSIDE_TRANSACTION = "hibernate.allow_update_outside_transaction"; + + /** + * When enabled, specifies that the {@link org.hibernate.Session} should be + * closed automatically at the end of each transaction. + * + * @settingDefault {@code false} + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyAutoClosing(boolean) + */ + String AUTO_CLOSE_SESSION = "hibernate.transaction.auto_close_session"; + + /** + * When enabled, specifies that automatic flushing should occur during the JTA + * {@link jakarta.transaction.Synchronization#beforeCompletion()} callback. + * + * @settingDefault {@code true} unless using JPA bootstrap + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyAutoFlushing(boolean) + */ + String FLUSH_BEFORE_COMPLETION = "hibernate.transaction.flush_before_completion"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ValidationSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/ValidationSettings.java new file mode 100644 index 0000000000..c20e51d629 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cfg/ValidationSettings.java @@ -0,0 +1,111 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.cfg; + +/** + * @author Steve Ebersole + */ +public interface ValidationSettings { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Indicates which {@linkplain jakarta.persistence.ValidationMode form of automatic + * validation} is in effect as per the rules defined in JPA 2 section 3.6.1.1. + *

+ * See JPA 2 sections 9.4.3 and 8.2.1.8 + * + * @see jakarta.persistence.ValidationMode + */ + String JAKARTA_VALIDATION_MODE = "jakarta.persistence.validation.mode"; + + /** + * Used to pass along any discovered {@link jakarta.validation.ValidatorFactory}. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyValidatorFactory(Object) + */ + String JAKARTA_VALIDATION_FACTORY = "jakarta.persistence.validation.factory"; + + /** + * Used to coordinate with bean validators. + *

+ * See JPA 2 section 8.2.1.9 + */ + @SuppressWarnings("unused") + String JAKARTA_PERSIST_VALIDATION_GROUP = "jakarta.persistence.validation.group.pre-persist"; + + /** + * Used to coordinate with bean validators. + *

+ * See JPA 2 section 8.2.1.9 + */ + @SuppressWarnings("unused") + String JAKARTA_UPDATE_VALIDATION_GROUP = "jakarta.persistence.validation.group.pre-update"; + + /** + * Used to coordinate with bean validators. + *

+ * See JPA 2 section 8.2.1.9 + */ + @SuppressWarnings("unused") + String JAKARTA_REMOVE_VALIDATION_GROUP = "jakarta.persistence.validation.group.pre-remove"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Hibernate settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Enable nullability checking, raises an exception if an attribute marked as + * {@linkplain jakarta.persistence.Basic#optional() not null} is null at runtime. + *

+ * Defaults to disabled if Bean Validation is present in the classpath and + * annotations are used, or enabled otherwise. + * + * @see org.hibernate.boot.SessionFactoryBuilder#applyNullabilityChecking(boolean) + */ + String CHECK_NULLABILITY = "hibernate.check_nullability"; + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Legacy JPA settings + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * @deprecated Use {@link #JAKARTA_VALIDATION_MODE} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_VALIDATION_MODE = "javax.persistence.validation.mode"; + + /** + * @deprecated Use {@link #JAKARTA_VALIDATION_FACTORY} instead + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + String JPA_VALIDATION_FACTORY = "javax.persistence.validation.factory"; + + /** + * @deprecated Use {@link #JAKARTA_PERSIST_VALIDATION_GROUP} instead + */ + @Deprecated + String JPA_PERSIST_VALIDATION_GROUP = "javax.persistence.validation.group.pre-persist"; + + /** + * @deprecated Use {@link #JAKARTA_UPDATE_VALIDATION_GROUP} instead + */ + @Deprecated + String JPA_UPDATE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-update"; + + /** + * @deprecated Use {@link #JAKARTA_REMOVE_VALIDATION_GROUP} instead + */ + @Deprecated + String JPA_REMOVE_VALIDATION_GROUP = "javax.persistence.validation.group.pre-remove"; +} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java index 0feaf008bd..ffcbe512cd 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java @@ -11,6 +11,7 @@ import java.util.Map; import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.BatchSettings; import org.hibernate.cfg.Environment; import org.hibernate.engine.jdbc.batch.spi.BatchBuilder; import org.hibernate.internal.util.config.ConfigurationHelper; @@ -28,13 +29,6 @@ public class BatchBuilderInitiator implements StandardServiceInitiator getServiceInitiated() { return BatchBuilder.class; @@ -42,15 +36,15 @@ public class BatchBuilderInitiator implements StandardServiceInitiator configurationValues, ServiceRegistryImplementor registry) { - Object builder = configurationValues.get( BUILDER ); + Object builder = configurationValues.get( BatchSettings.BUILDER ); if ( builder == null ) { - builder = configurationValues.get( AvailableSettings.BATCH_STRATEGY ); + builder = configurationValues.get( BatchSettings.BATCH_STRATEGY ); } if ( builder == null ) { return new BatchBuilderImpl( - ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, 1 ) + ConfigurationHelper.getInt( BatchSettings.STATEMENT_BATCH_SIZE, configurationValues, 1 ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java index e61f7da118..07663c861c 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java @@ -17,7 +17,7 @@ import org.hibernate.service.Service; * A builder for {@link Batch} instances. *

* A custom {@code BatchBuilder} may be selected using the configuration property - * {@value org.hibernate.cfg.AvailableSettings#BATCH_STRATEGY}. + * {@value org.hibernate.cfg.AvailableSettings#BUILDER}. * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java index f3619ad4d8..3dd388a773 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java @@ -20,6 +20,8 @@ import org.hibernate.HibernateException; import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.C3p0Settings; +import org.hibernate.cfg.ProxoolSettings; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; @@ -77,7 +79,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator LEGACY_CONNECTION_PROVIDER_MAPPING = Map.of( + private static final Map LEGACY_CONNECTION_PROVIDER_MAPPING = Map.of( "org.hibernate.connection.DatasourceConnectionProvider", DatasourceConnectionProviderImpl.class.getName(), @@ -94,7 +96,9 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator configurationValues, ServiceRegistryImplementor registry) { + public ConnectionProvider initiateService( + Map configurationValues, + ServiceRegistryImplementor registry) { if ( isMultiTenancyEnabled( registry ) ) { // nothing to do, but given the separate hierarchies have to handle this here. return null; @@ -148,7 +152,8 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator singleRegisteredProvider = getSingleRegisteredProvider( strategySelector ); + final Class singleRegisteredProvider = getSingleRegisteredProvider( + strategySelector ); if ( singleRegisteredProvider != null ) { try { connectionProvider = singleRegisteredProvider.newInstance(); @@ -200,7 +205,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator injectionData = (Map) configurationValues.get( INJECTION_DATA ); + final Map injectionData = (Map) configurationValues.get( INJECTION_DATA ); if ( injectionData != null && injectionData.size() > 0 ) { final ConnectionProvider theConnectionProvider = connectionProvider; new BeanInfoHelper( connectionProvider.getClass() ).applyToBeanInfo( @@ -244,7 +249,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator configValues) { for ( String key : configValues.keySet() ) { - if ( key.startsWith( AvailableSettings.C3P0_CONFIG_PREFIX ) ) { + if ( key.startsWith( C3p0Settings.C3P0_CONFIG_PREFIX + "." ) ) { return true; } } @@ -255,7 +260,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator configValues) { for ( String key : configValues.keySet() ) { - if ( key.startsWith( AvailableSettings.PROXOOL_CONFIG_PREFIX ) ) { + if ( key.startsWith( ProxoolSettings.PROXOOL_CONFIG_PREFIX ) ) { return true; } } @@ -274,7 +279,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator properties) { + public static Properties getConnectionProperties(Map properties) { final Properties result = new Properties(); - for ( Map.Entry entry : properties.entrySet() ) { - if ( !(entry.getKey() instanceof String) || !(entry.getValue() instanceof String) ) { + for ( Map.Entry entry : properties.entrySet() ) { + if ( !( entry.getKey() instanceof String ) || !( entry.getValue() instanceof String ) ) { continue; } final String key = (String) entry.getKey(); @@ -379,7 +384,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator SPECIAL_PROPERTIES; - private static final Map ISOLATION_VALUE_MAP; + private static final Map ISOLATION_VALUE_MAP; private static final Map ISOLATION_VALUE_CONSTANT_NAME_MAP; private static final Map ISOLATION_VALUE_NICE_NAME_MAP; @@ -503,4 +508,27 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator settings, String... names) { + for ( int i = 0; i < names.length; i++ ) { + if ( settings.containsKey( names[i] ) ) { + return (String) settings.get( names[i] ); + } + } + return null; + } + + @FunctionalInterface + public interface SettingConsumer { + void consumeSetting(String name, String value); + } + + public static void consumeSetting(Map settings, SettingConsumer consumer, String... names) { + for ( int i = 0; i < names.length; i++ ) { + if ( settings.containsKey( names[i] ) ) { + consumer.consumeSetting( names[i], (String) settings.get( names[i] ) ); + return; + } + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/DataSourceBasedMultiTenantConnectionProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/DataSourceBasedMultiTenantConnectionProviderImpl.java index 82721465d2..98177c1fbb 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/DataSourceBasedMultiTenantConnectionProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/DataSourceBasedMultiTenantConnectionProviderImpl.java @@ -13,12 +13,15 @@ import javax.sql.DataSource; import org.hibernate.HibernateException; import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.MultiTenancySettings; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.jndi.spi.JndiService; import org.hibernate.service.spi.ServiceRegistryAwareService; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.Stoppable; +import static org.hibernate.cfg.MultiTenancySettings.TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY; + /** * A concrete implementation of the {@link MultiTenantConnectionProvider} contract bases on a number of * reasonable assumptions. We assume that:

    @@ -28,7 +31,7 @@ import org.hibernate.service.spi.Stoppable; * *
  • * {@value AvailableSettings#DATASOURCE} is a string naming either the {@literal any} - * data source or the base JNDI context. If the latter, {@link #TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY} must + * data source or the base JNDI context. If the latter, {@link MultiTenancySettings#TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY} must * also be set. *
  • *
@@ -39,11 +42,6 @@ public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl implements ServiceRegistryAwareService, Stoppable { - /** - * Identifies the DataSource name to use for {@link #selectAnyDataSource} handling - */ - public static final String TENANT_IDENTIFIER_TO_USE_FOR_ANY_KEY = "hibernate.multi_tenant.datasource.identifier_for_any"; - private Map dataSourceMap; private JndiService jndiService; private String tenantIdentifierForAny; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionPoolingLogger.java b/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionPoolingLogger.java index 2e58357245..e700e12440 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionPoolingLogger.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionPoolingLogger.java @@ -71,8 +71,8 @@ public interface ConnectionPoolingLogger extends BasicLogger { void usingUrl(String url); @LogMessage(level = WARN) - @Message(value = "No JDBC Driver class was specified by property %s", id = 10001006) - void jdbcDriverNotSpecified(String driver); + @Message(id = 10001006, value = "No JDBC Driver class was specified by property `jakarta.persistence.jdbc.driver`, `hibernate.driver` or `javax.persistence.jdbc.driver`") + void jdbcDriverNotSpecified(); @LogMessage(level = INFO) @Message(value = "JDBC isolation level: %s", id = 10001007) diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java index 87045f0ea8..3a9e73c9c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java @@ -122,6 +122,9 @@ import static org.hibernate.cfg.AvailableSettings.SESSION_FACTORY_NAME; import static org.hibernate.cfg.AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY; import static org.hibernate.cfg.AvailableSettings.URL; import static org.hibernate.cfg.AvailableSettings.USER; +import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT; +import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_DIRTY_TRACKING; +import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_LAZY_INITIALIZATION; import static org.hibernate.internal.HEMLogging.messageLogger; import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER; @@ -305,7 +308,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil // container situations, calling back into PersistenceUnitInfo#addClassTransformer final boolean dirtyTrackingEnabled; - Object propertyValue = configurationValues.remove( AvailableSettings.ENHANCER_ENABLE_DIRTY_TRACKING ); + Object propertyValue = configurationValues.remove( ENHANCER_ENABLE_DIRTY_TRACKING ); if ( propertyValue != null ) { dirtyTrackingEnabled = Boolean.parseBoolean( propertyValue.toString() ); } @@ -313,19 +316,19 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil dirtyTrackingEnabled = true; } final boolean lazyInitializationEnabled; - propertyValue = configurationValues.remove( AvailableSettings.ENHANCER_ENABLE_LAZY_INITIALIZATION ); + propertyValue = configurationValues.remove( ENHANCER_ENABLE_LAZY_INITIALIZATION ); if ( propertyValue != null ) { lazyInitializationEnabled = Boolean.parseBoolean( propertyValue.toString() ); } else { lazyInitializationEnabled = true; } - final boolean associationManagementEnabled = readBooleanConfigurationValue( AvailableSettings.ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT ); + final boolean associationManagementEnabled = readBooleanConfigurationValue( ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT ); if ( !lazyInitializationEnabled ) { - DEPRECATION_LOGGER.deprecatedSettingForRemoval( AvailableSettings.ENHANCER_ENABLE_LAZY_INITIALIZATION, "true" ); + DEPRECATION_LOGGER.deprecatedSettingForRemoval( ENHANCER_ENABLE_LAZY_INITIALIZATION, "true" ); } if ( !dirtyTrackingEnabled ) { - DEPRECATION_LOGGER.deprecatedSettingForRemoval( AvailableSettings.ENHANCER_ENABLE_DIRTY_TRACKING, "true" ); + DEPRECATION_LOGGER.deprecatedSettingForRemoval( ENHANCER_ENABLE_DIRTY_TRACKING, "true" ); } if ( dirtyTrackingEnabled || lazyInitializationEnabled || associationManagementEnabled ) { diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java index ec46819dc2..9b18955849 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java @@ -22,6 +22,8 @@ import org.jboss.logging.Logger; import org.checkerframework.checker.nullness.qual.Nullable; +import static org.hibernate.cfg.StatisticsSettings.STATS_BUILDER; + /** * @author Steve Ebersole */ @@ -30,12 +32,6 @@ public class StatisticsInitiator implements SessionFactoryServiceInitiator getServiceInitiated() { return StatisticsImplementor.class; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingTest.java index b3fa77b02f..530c39bc1c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/insertordering/InsertOrderingTest.java @@ -9,6 +9,7 @@ package org.hibernate.orm.test.insertordering; import java.util.Iterator; import java.util.function.Supplier; +import org.hibernate.cfg.BatchSettings; import org.hibernate.cfg.Environment; import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator; import org.hibernate.engine.jdbc.batch.internal.BatchImpl; @@ -35,9 +36,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; ) @SessionFactory @ServiceRegistry( - settings = {@Setting( name = Environment.ORDER_INSERTS, value = "true"), - @Setting( name = Environment.STATEMENT_BATCH_SIZE, value = "10"), - @Setting( name = BatchBuilderInitiator.BUILDER, value = "org.hibernate.orm.test.insertordering.InsertOrderingTest$StatsBatchBuilder" ) + settings = {@Setting( name = BatchSettings.ORDER_INSERTS, value = "true"), + @Setting( name = BatchSettings.STATEMENT_BATCH_SIZE, value = "10"), + @Setting( name = BatchSettings.BUILDER, value = "org.hibernate.orm.test.insertordering.InsertOrderingTest$StatsBatchBuilder" ) } ) public class InsertOrderingTest { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/FailingAddToBatchTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/FailingAddToBatchTest.java index 1e43d909eb..7ebcd828dd 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/FailingAddToBatchTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/FailingAddToBatchTest.java @@ -6,8 +6,7 @@ */ package org.hibernate.orm.test.jpa.transaction.batch; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator; +import org.hibernate.cfg.BatchSettings; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; @@ -30,11 +29,11 @@ import static org.assertj.core.api.Assertions.assertThat; FailingAddToBatchTest.MyEntity.class }, integrationSettings = { - @Setting(name = AvailableSettings.STATEMENT_BATCH_SIZE, value = "50") + @Setting(name = BatchSettings.STATEMENT_BATCH_SIZE, value = "50") }, settingProviders = { @SettingProvider( - settingName = BatchBuilderInitiator.BUILDER, + settingName = BatchSettings.BUILDER, provider = AbstractBatchingTest.ErrorBatch2BuilderSettingProvider.class ) } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithFailingBatchTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithFailingBatchTest.java index 280b4eda49..102a3ffbcc 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithFailingBatchTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithFailingBatchTest.java @@ -7,7 +7,7 @@ package org.hibernate.orm.test.jpa.transaction.batch; import org.hibernate.cfg.AvailableSettings; -import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator; +import org.hibernate.cfg.BatchSettings; import org.hibernate.orm.test.jpa.transaction.JtaPlatformSettingProvider; import org.hibernate.testing.TestForIssue; @@ -53,7 +53,7 @@ import static org.junit.jupiter.api.Assertions.fail; provider = JtaPlatformSettingProvider.class ), @SettingProvider( - settingName = BatchBuilderInitiator.BUILDER, + settingName = BatchSettings.BUILDER, provider = AbstractBatchingTest.ErrorBatch2BuilderSettingProvider.class ) } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithStatementsBatchTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithStatementsBatchTest.java index 7712eac597..3e7fbf02c1 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithStatementsBatchTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/transaction/batch/JtaWithStatementsBatchTest.java @@ -7,7 +7,7 @@ package org.hibernate.orm.test.jpa.transaction.batch; import org.hibernate.cfg.AvailableSettings; -import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator; +import org.hibernate.cfg.BatchSettings; import org.hibernate.orm.test.jpa.transaction.JtaPlatformSettingProvider; import org.hibernate.testing.TestForIssue; @@ -54,7 +54,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; provider = JtaPlatformSettingProvider.class ), @SettingProvider( - settingName = BatchBuilderInitiator.BUILDER, + settingName = BatchSettings.BUILDER, provider = AbstractBatchingTest.Batch2BuilderSettingProvider.class ) } diff --git a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java index b4d3b67fe9..80831de868 100644 --- a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java +++ b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java @@ -11,10 +11,13 @@ import java.util.Map; import java.util.Properties; import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.JdbcSettings; import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator; import com.zaxxer.hikari.HikariConfig; +import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.consumeSetting; + /** * Utility class to map Hibernate properties to HikariCP configuration properties. * @@ -33,12 +36,43 @@ public class HikariConfigurationUtil { */ public static HikariConfig loadConfiguration(Map props) { Properties hikariProps = new Properties(); - copyProperty( AvailableSettings.AUTOCOMMIT, props, "autoCommit", hikariProps ); + copyProperty( JdbcSettings.AUTOCOMMIT, props, "autoCommit", hikariProps ); - copyProperty( AvailableSettings.DRIVER, props, "driverClassName", hikariProps ); - copyProperty( AvailableSettings.URL, props, "jdbcUrl", hikariProps ); - copyProperty( AvailableSettings.USER, props, "username", hikariProps ); - copyProperty( AvailableSettings.PASS, props, "password", hikariProps ); + copyProperty( + props, + "driverClassName", + hikariProps, + JdbcSettings.JAKARTA_JDBC_DRIVER, + JdbcSettings.DRIVER, + JdbcSettings.JPA_JDBC_DRIVER + ); + + copyProperty( + props, + "jdbcUrl", + hikariProps, + JdbcSettings.JAKARTA_JDBC_URL, + JdbcSettings.URL, + JdbcSettings.JPA_JDBC_URL + ); + + copyProperty( + props, + "username", + hikariProps, + JdbcSettings.JAKARTA_JDBC_USER, + JdbcSettings.USER, + JdbcSettings.JPA_JDBC_USER + ); + + copyProperty( + props, + "password", + hikariProps, + AvailableSettings.JAKARTA_JDBC_PASSWORD, + AvailableSettings.PASS, + AvailableSettings.JPA_JDBC_PASSWORD + ); copyIsolationSetting( props, hikariProps ); @@ -57,6 +91,14 @@ public class HikariConfigurationUtil { } } + private static void copyProperty(Map src, String dstKey, Properties dst, String... srcKeys) { + consumeSetting( + src, + (name, value) -> dst.setProperty( dstKey, value ), + srcKeys + ); + } + private static void copyIsolationSetting(Map props, Properties hikariProps) { final Integer isolation = ConnectionProviderInitiator.extractIsolation( props ); if ( isolation != null ) { diff --git a/hibernate-proxool/src/main/java/org/hibernate/proxool/internal/ProxoolConnectionProvider.java b/hibernate-proxool/src/main/java/org/hibernate/proxool/internal/ProxoolConnectionProvider.java index 809db92609..eba9972658 100644 --- a/hibernate-proxool/src/main/java/org/hibernate/proxool/internal/ProxoolConnectionProvider.java +++ b/hibernate-proxool/src/main/java/org/hibernate/proxool/internal/ProxoolConnectionProvider.java @@ -17,7 +17,8 @@ import java.util.Properties; import org.hibernate.HibernateException; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; -import org.hibernate.cfg.Environment; +import org.hibernate.cfg.JdbcSettings; +import org.hibernate.cfg.ProxoolSettings; import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.internal.util.StringHelper; @@ -110,19 +111,19 @@ public class ProxoolConnectionProvider @Override public void configure(Map props) { // Get the configurator files (if available) - final String jaxpFile = (String) props.get( Environment.PROXOOL_XML ); - final String propFile = (String) props.get( Environment.PROXOOL_PROPERTIES ); - final String externalConfig = (String) props.get( Environment.PROXOOL_EXISTING_POOL ); + final String jaxpFile = (String) props.get( ProxoolSettings.PROXOOL_XML ); + final String propFile = (String) props.get( ProxoolSettings.PROXOOL_PROPERTIES ); + final String externalConfig = (String) props.get( ProxoolSettings.PROXOOL_EXISTING_POOL ); // Default the Proxool alias setting - proxoolAlias = (String) props.get( Environment.PROXOOL_POOL_ALIAS ); + proxoolAlias = (String) props.get( ProxoolSettings.PROXOOL_POOL_ALIAS ); // Configured outside of Hibernate (i.e. Servlet container, or Java Bean Container // already has Proxool pools running, and this provider is to just borrow one of these if ( "true".equals( externalConfig ) ) { // Validate that an alias name was provided to determine which pool to use if ( !StringHelper.isNotEmpty( proxoolAlias ) ) { - final String msg = PROXOOL_MESSAGE_LOGGER.unableToConfigureProxoolProviderToUseExistingInMemoryPool( Environment.PROXOOL_POOL_ALIAS ); + final String msg = PROXOOL_MESSAGE_LOGGER.unableToConfigureProxoolProviderToUseExistingInMemoryPool( ProxoolSettings.PROXOOL_POOL_ALIAS ); PROXOOL_LOGGER.error( msg ); throw new HibernateException( msg ); } @@ -141,7 +142,7 @@ public class ProxoolConnectionProvider // Validate that an alias name was provided to determine which pool to use if ( !StringHelper.isNotEmpty( proxoolAlias ) ) { - final String msg = PROXOOL_MESSAGE_LOGGER.unableToConfigureProxoolProviderToUseJaxp( Environment.PROXOOL_POOL_ALIAS ); + final String msg = PROXOOL_MESSAGE_LOGGER.unableToConfigureProxoolProviderToUseJaxp( ProxoolSettings.PROXOOL_POOL_ALIAS ); PROXOOL_LOGGER.error( msg ); throw new HibernateException( msg ); } @@ -166,7 +167,7 @@ public class ProxoolConnectionProvider // Validate that an alias name was provided to determine which pool to use if ( !StringHelper.isNotEmpty( proxoolAlias ) ) { - final String msg = PROXOOL_MESSAGE_LOGGER.unableToConfigureProxoolProviderToUsePropertiesFile( Environment.PROXOOL_POOL_ALIAS ); + final String msg = PROXOOL_MESSAGE_LOGGER.unableToConfigureProxoolProviderToUsePropertiesFile( ProxoolSettings.PROXOOL_POOL_ALIAS ); PROXOOL_LOGGER.error( msg ); throw new HibernateException( msg ); } @@ -189,7 +190,7 @@ public class ProxoolConnectionProvider isolation = ConnectionProviderInitiator.extractIsolation( props ); PROXOOL_MESSAGE_LOGGER.jdbcIsolationLevel( ConnectionProviderInitiator.toIsolationNiceName( isolation ) ); - autocommit = ConfigurationHelper.getBoolean( Environment.AUTOCOMMIT, props ); + autocommit = ConfigurationHelper.getBoolean( JdbcSettings.AUTOCOMMIT, props ); PROXOOL_MESSAGE_LOGGER.autoCommitMode( autocommit ); } diff --git a/local-build-plugins/gradle/wrapper/gradle-wrapper.jar b/local-build-plugins/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 43784 zcmZs?V{~Rwvn?Fkwrv}oj&0kv`NZkiwrxGJZ6_V8V;h}(ea=1Oz4wgq{n%sG*sJ#5 zf2!7;yQ=2UEO`74IHZy+I0QzrvO8uX9y%ySa?mnvqNLV8{0DVViJKuj_{N|8_y>I+MxT2rn3@Q#>wn~1E zL?7Lobaaai$f~PJ0h}NW%Jz=o9G(v`1G-hf3`!4Hykd#lU+;7v>s6JhQ7>+NykDU( z+Yh)P+pD#Xf_Ezp%e``u9= zPJL0(x6YXP{nVHO6?>|5I(OEX+z0Fdei~>3M`J^9Le#>-%*cHO2dI9HaE61$a74)& zhG`72UvRy2>GhSbe7%JS*{^BAj@7^R_`#yP-hcCvM0hriNtFRwQ8sdle)1Ez%QcHa$>LXwe6Dl*#&-bzELzYX(EA*tDQjPTN z_Iy$>1z$iZhRJU_kP-6fwFoL`ATuxgebp735D2?M!BWyU#RUSYV9ge!Wt(Ryg2c# zE!mNwc?3zLL{3iQ6)y8~c~s=m4Xqg@K3wMbk>I?_-Uz?T$HzrkC9iM}Pe>ON*;6DX zAAhT%>H<2)Tbb?04j7l5tjnh^NK&u3&|8|x9FUM@&C|WbNe>8;>Zst)1WXai?2}(@ zyKj-PO(w)jgcXLvm(rNz(X6t9Y6OW>TfRtL8F0CuNP|)h%mfKHTyb}1*+arFxFC1U z(N0B0N3Jcz26y6Ul(ROd=0s+E8`mO|%&tmuVsXf&%C< zqfuZ+k9Lczb4Li|3N*~kFWFblf~n^$3YVNq6NL&>E`&s_PXoyxkILoa7=DUIu3pa^ zbjt28Iln9>aXD?uYDI=>%f%@nd!*sacDx%hqN>9K2$r2N)@*sA+415I5pr2{acy3O z0sue0u{}YluJrg2MMai%uCnAS|1>N{x) z9W0h;+;^Q;m5Y1Pds=9%6L2UE$|ziEl`q?2-MJyt_O1MjCN!fwl1)PARjh-GPK-Bu ziBk^EHui_QP^405zFUzBY86#gXxXo~tO_j7sEQS_To{@n19bS|pHyoI$71br)Bq_% zKI<_wiEE{M!;;7m75H6Py81{;GMa{JeMKsHeh#zwafm})ycBUB89KUwLH+8iM(-enyqKq)oHH3hDjL8_*Fweo|@|9cT%{f zO-v5t@vOg5-KrPTr2t#GYJ)8@zQ@<478@tOj3h9r#~9`^Q#5+^aL}Wv7*J`&+|Vx@ z)BRL(#kD~Mwr_&pUDQs^fLcl~6?LZC$n&r)&u_?6eu_~zyQ*6+FP*qf$#iHG z2YPE|ZZ@No$<*C$7mSO|AFFFO$1DJum^n0}UN;9_VcV$ZMmrK0={c8_%D=nHmaMXi zLn410cRCiWs7{vSsL)&F+tZG2uyQKop$)mm`wetpa|?aR02T6+0J}-$e5Tw~i$ci59}-vZrgrm4909wfTB||ALOyJi_vsmyzG1%`*ElF%_(8r&emW?qs1{D6NY1hdkN6 z07ItKp8bQ!olQMB3Sen0Jy&kX17H59sC?9IOo92e=7EBncWnkSS&@h??=N|%=F1hG zSGJ+o9GvdE<*GX#`6P4GIp->PzJbw*4h;0=NT7%~D)9MW>0b$q#fS zPQU+~T!DiVv3L&u&UQ{7s>gh_Y{*s{)!Z3MmJJ5VyQyVm4*h!+mLYlbxHc7^s-Z|7u?n}w zt~M(a2Sx*m2>=rstd3iQH+HVUSiz-O6tq{s70C%sK{WQ;xh7kT+&hBZD(hK{7|Y4N z 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�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 Qc)^b}ObCdTt-n6~KSqm+J^%m! delta 39466 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 Ar2qf` diff --git a/local-build-plugins/gradle/wrapper/gradle-wrapper.properties b/local-build-plugins/gradle/wrapper/gradle-wrapper.properties index be52383ef4..9f4197d5f4 100644 --- a/local-build-plugins/gradle/wrapper/gradle-wrapper.properties +++ b/local-build-plugins/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/local-build-plugins/gradlew b/local-build-plugins/gradlew index 4f906e0c81..fcb6fca147 100644 --- a/local-build-plugins/gradlew +++ b/local-build-plugins/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,98 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +118,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +129,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/local-build-plugins/gradlew.bat b/local-build-plugins/gradlew.bat index 107acd32c4..93e3f59f13 100644 --- a/local-build-plugins/gradlew.bat +++ b/local-build-plugins/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/AsciiDocWriter.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/AsciiDocWriter.java index 55f593c574..3004ea90be 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/AsciiDocWriter.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/AsciiDocWriter.java @@ -12,8 +12,8 @@ import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.nio.file.Files; +import java.util.Locale; import java.util.Map; -import java.util.SortedMap; import java.util.SortedSet; import org.gradle.api.Project; @@ -23,11 +23,10 @@ import org.gradle.api.file.RegularFile; * @author Marko Bekhta */ public class AsciiDocWriter { - public static final String ANCHOR_BASE = "settings-"; - public static final String ANCHOR_START = "[[" + ANCHOR_BASE; public static void writeToFile( - SortedMap> settingDescriptorMap, + String anchorNameBase, + Map> settingDescriptorMap, RegularFile outputFile, Project project) { final File outputFileAsFile = outputFile.getAsFile(); @@ -39,7 +38,7 @@ public class AsciiDocWriter { } try ( FileWriter fileWriter = new FileWriter( outputFileAsFile ) ) { - write( settingDescriptorMap, fileWriter, project ); + write( anchorNameBase, settingDescriptorMap, fileWriter, project ); } catch (IOException e) { throw new RuntimeException( "Failed to produce asciidoc output for collected properties", e ); @@ -47,30 +46,35 @@ public class AsciiDocWriter { } private static void write( - SortedMap> settingDescriptorMap, + String anchorNameBase, + Map> settingDescriptorMap, FileWriter writer, Project project) throws IOException { for ( Map.Entry> entry : settingDescriptorMap.entrySet() ) { final SettingsDocSection sectionDescriptor = entry.getKey(); final SortedSet sectionSettingDescriptors = entry.getValue(); + if ( sectionSettingDescriptors.isEmpty() ) { + continue; + } - final Project sourceProject = project.getRootProject().project( sectionDescriptor.getProjectPath() ); + final String sectionName = sectionDescriptor.getName(); - // write an anchor in the form `[[settings-{moduleName}]]`, e.g. `[[settings-hibernate-core]]` - tryToWriteLine( writer, ANCHOR_START, sourceProject.getName(), "]]" ); - tryToWriteLine( writer, "=== ", "(", sourceProject.getName(), ") ", sourceProject.getDescription() ); + // write an anchor in the form `[[{anchorNameBase}-{sectionName}]]` + tryToWriteLine( writer, "[[", anchorNameBase, "-", sectionName, "]]" ); + tryToWriteLine( writer, "=== ", sectionDescriptor.getSummary() ); writer.write( '\n' ); for ( SettingDescriptor settingDescriptor : sectionSettingDescriptors ) { - writeSettingAnchor( settingDescriptor, writer ); + // write an anchor in the form `[[{anchorNameBase}-{settingName}]]` + tryToWriteLine( writer, "[[", anchorNameBase, "-", settingDescriptor.getName(), "]]" ); writeSettingName( settingDescriptor, writer ); writer.write( "::\n" ); - writeLifecycleNotes( settingDescriptor, writer ); + writeMetadata( settingDescriptor, writer ); - writer.write( settingDescriptor.getJavadoc() ); + writer.write( settingDescriptor.getComment() ); writer.write( "\n\n'''\n" ); } @@ -79,19 +83,54 @@ public class AsciiDocWriter { } } - private static void writeLifecycleNotes(SettingDescriptor settingDescriptor, FileWriter writer) throws IOException { - // NOTE : at the moment, there is at least one setting that is both which fundamentally seems wrong - if ( settingDescriptor.isIncubating() ) { - writer.write( "NOTE:: _This setting is considered incubating_\n\n" ); + private static void writeMetadata(SettingDescriptor settingDescriptor, FileWriter writer) throws IOException { + if ( !settingDescriptor.hasMetadata() ) { + return; } - if ( settingDescriptor.isDeprecated() ) { - writer.write( "WARN:: _This setting is considered deprecated_\n\n" ); + + writer.write( "+\n" ); + writer.write( "****\n" ); + + writer.write( + String.format( + Locale.ROOT, + "**See:** %s[%s.%s]\n\n", + settingDescriptor.getPublishedJavadocLink(), + Utils.withoutPackagePrefix( settingDescriptor.getSettingsClassName() ), + settingDescriptor.getSettingFieldName() + ) + ); + + // NOTE : Asciidoctor requires that italic always be the innermost formatting + + final SettingDescriptor.LifecycleDetails lifecycleDetails = settingDescriptor.getLifecycleDetails(); + + // NOTE : at the moment, there is at least one setting that is incubating AND deprecated which fundamentally seems wrong + if ( lifecycleDetails.isIncubating() ) { + writer.write( "NOTE: *_This setting is considered incubating_*\n\n" ); } + if ( lifecycleDetails.isDeprecated() ) { + writer.write( "WARNING: *_This setting is considered deprecated_*\n\n" ); + } + + if ( lifecycleDetails.getSince() != null ) { + writer.write( "*_Since:_* _" + lifecycleDetails.getSince() + "_\n\n" ); + } + + if ( settingDescriptor.getDefaultValue() != null ) { + writer.write( "*_Default Value:_* " + settingDescriptor.getDefaultValue() + "\n\n" ); + } + + if ( settingDescriptor.getApiNote() != null ) { + writer.write( settingDescriptor.getApiNote() + "\n\n" ); + } + + writer.write( "****\n+\n" ); } private static void writeSettingName(SettingDescriptor settingDescriptor, FileWriter writer) throws IOException { writer.write( "`" ); - if ( settingDescriptor.isDeprecated() ) { + if ( settingDescriptor.getLifecycleDetails().isDeprecated() ) { writer.write( "[.line-through]#" ); } else { @@ -100,7 +139,7 @@ public class AsciiDocWriter { writer.write( settingDescriptor.getName() ); - if ( settingDescriptor.isDeprecated() ) { + if ( settingDescriptor.getLifecycleDetails().isDeprecated() ) { writer.write( '#' ); } else { @@ -109,12 +148,6 @@ public class AsciiDocWriter { writer.write( '`' ); } - private static void writeSettingAnchor(SettingDescriptor settingDescriptor, Writer writer) throws IOException { - writer.write( ANCHOR_START ); - writer.write( settingDescriptor.getName() ); - writer.write( "]] " ); - } - private static void tryToWriteLine(Writer writer, String prefix, String value, String... other) { try { writer.write( prefix ); diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptor.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptor.java index 5b0f85c362..754512bc28 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptor.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptor.java @@ -6,36 +6,58 @@ */ package org.hibernate.orm.properties; -import java.util.Comparator; - -import static java.util.Comparator.comparing; - /** * @author Steve Ebersole */ public class SettingDescriptor { - public static final Comparator BY_NAME = comparing( SettingDescriptor::getName ); - private final String name; private final String settingsClassName; private final String settingFieldName; - private final String javadoc; - private final boolean deprecated; - private final boolean incubating; + private final String publishedJavadocLink; + private final String comment; + private final String defaultValue; + private final String apiNote; + private final LifecycleDetails lifecycleDetails; public SettingDescriptor( String name, String settingsClassName, String settingFieldName, - String javadoc, - boolean deprecated, - boolean incubating) { + String publishedJavadocLink, + String comment, + String defaultValue, + String apiNote, + LifecycleDetails lifecycleDetails) { this.name = name; this.settingsClassName = settingsClassName; this.settingFieldName = settingFieldName; - this.javadoc = javadoc; - this.deprecated = deprecated; - this.incubating = incubating; + this.comment = comment; + this.publishedJavadocLink = publishedJavadocLink; + this.defaultValue = defaultValue; + this.apiNote = apiNote; + this.lifecycleDetails = lifecycleDetails; + } + + public SettingDescriptor( + String name, + String settingsClassName, + String settingFieldName, + String publishedJavadocLink, + String comment, + String defaultValue, + String apiNote, + String since, + boolean deprecated, + boolean incubating) { + this( + name, + settingsClassName, + settingFieldName, + publishedJavadocLink, comment, + defaultValue, + apiNote, + new LifecycleDetails( since, deprecated, incubating ) + ); } /** @@ -48,8 +70,26 @@ public class SettingDescriptor { /** * The Javadoc content */ - public String getJavadoc() { - return javadoc; + public String getComment() { + return comment; + } + + public String getPublishedJavadocLink() { + return publishedJavadocLink; + } + + /** + * The setting's default value + */ + public String getDefaultValue() { + return defaultValue; + } + + /** + * {@code @apiNote} defined on the setting field + */ + public String getApiNote() { + return apiNote; } public String getSettingsClassName() { @@ -60,11 +100,60 @@ public class SettingDescriptor { return settingFieldName; } - public boolean isDeprecated() { - return deprecated; + public LifecycleDetails getLifecycleDetails() { + return lifecycleDetails; } - public boolean isIncubating() { - return incubating; + public boolean hasMetadata() { + return defaultValue != null + || apiNote != null + || lifecycleDetails.since != null + || lifecycleDetails.incubating + || lifecycleDetails.deprecated; + } + + @Override + public String toString() { + return "setting(" + name + ") {\n" + + " settingsClassName = `" + settingsClassName + "`,\n" + + " settingFieldName = `" + settingFieldName + "`,\n" + + " lifecycle = " + lifecycleDetails + ",\n" + + " defaultValue = `" + defaultValue + "`,\n" + + " apiNote = `" + apiNote + "`,\n" + + " javadoc = ```\n" + comment + "\n```\n" + + "}"; + } + + public static class LifecycleDetails { + private final String since; + private final boolean incubating; + private final boolean deprecated; + + public LifecycleDetails(String since, boolean deprecated, boolean incubating) { + this.since = since; + this.deprecated = deprecated; + this.incubating = incubating; + } + + public String getSince() { + return since; + } + + public boolean isDeprecated() { + return deprecated; + } + + public boolean isIncubating() { + return incubating; + } + + @Override + public String toString() { + return "{\n" + + " since = `" + since + "`,\n" + + " incubating = `" + incubating + "`,\n" + + " deprecated = `" + deprecated + "`\n" + + " }"; + } } } diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptorComparator.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptorComparator.java new file mode 100644 index 0000000000..d6a2f22274 --- /dev/null +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingDescriptorComparator.java @@ -0,0 +1,56 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.orm.properties; + +import java.util.Comparator; + +/** + * Sorts {@link SettingDescriptor} references by setting name with the following precedence -
    + *
  1. starts with {@code jakarta.persistence.}
  2. + *
  3. starts with {@code hibernate.}
  4. + *
  5. starts with {@code javax.persistence.}
  6. + *
  7. any others (should be none)
  8. + *
+ * + * @author Steve Ebersole + */ +public class SettingDescriptorComparator implements Comparator { + public static final SettingDescriptorComparator INSTANCE = new SettingDescriptorComparator(); + + public static final String JPA_PREFIX = "jakarta.persistence."; + public static final String HIBERNATE_PREFIX = "hibernate."; + public static final String LEGACY_JPA_PREFIX = "javax.persistence."; + + @Override + public int compare(SettingDescriptor o1, SettingDescriptor o2) { + if ( o1.getName().startsWith( JPA_PREFIX ) ) { + if ( o2.getName().startsWith( JPA_PREFIX ) ) { + return o1.getName().compareTo( o2.getName() ); + } + return -1; + } + + if ( o1.getName().startsWith( HIBERNATE_PREFIX ) ) { + if ( o2.getName().startsWith( JPA_PREFIX ) ) { + return 1; + } + if ( o2.getName().startsWith( HIBERNATE_PREFIX ) ) { + return o1.getName().compareTo( o2.getName() ); + } + return -1; + } + + assert o1.getName().startsWith( LEGACY_JPA_PREFIX ); + + if ( o2.getName().startsWith( JPA_PREFIX ) + || o2.getName().startsWith( HIBERNATE_PREFIX ) ) { + return 1; + } + + return o1.getName().compareTo( o2.getName() ); + } +} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingWorkingDetails.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingWorkingDetails.java new file mode 100644 index 0000000000..d6dbd0b277 --- /dev/null +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingWorkingDetails.java @@ -0,0 +1,140 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.orm.properties; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Steve Ebersole + */ +public class SettingWorkingDetails { + private final String name; + private final String settingsClassName; + private final String settingFieldName; + private final String publishedJavadocLink; + + private String defaultValue; + private String apiNote; + private String since; + private boolean deprecated; + private boolean incubating; + private List relatedSettingNames; + + public SettingWorkingDetails( + String name, + String settingsClassName, + String settingFieldName, + String publishedJavadocLink) { + this.name = name; + this.settingsClassName = settingsClassName; + this.settingFieldName = settingFieldName; + this.publishedJavadocLink = publishedJavadocLink; + } + + public String getName() { + return name; + } + + public String getSettingsClassName() { + return settingsClassName; + } + + public String getSettingFieldName() { + return settingFieldName; + } + + public String getPublishedJavadocLink() { + return publishedJavadocLink; + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public String getApiNote() { + return apiNote; + } + + public void setApiNote(String apiNote) { + this.apiNote = apiNote; + } + + public String getSince() { + return since; + } + + public void setSince(String since) { + this.since = since; + } + + public boolean isDeprecated() { + return deprecated; + } + + public void setDeprecated(boolean deprecated) { + this.deprecated = deprecated; + } + + public boolean isIncubating() { + return incubating; + } + + public void setIncubating(boolean incubating) { + this.incubating = incubating; + } + + public List getRelatedSettingNames() { + return relatedSettingNames; + } + + public void addRelatedSettingName(String settingName) { + if ( relatedSettingNames == null ) { + relatedSettingNames = new ArrayList<>(); + } + relatedSettingNames.add( settingName ); + } + + public SettingDescriptor buildDescriptor(String asciidoc) { + if ( name == null ) { + throw new IllegalStateException( "Setting name not specified" ); + } + + if ( settingsClassName == null ) { + throw new IllegalStateException( "Setting constant class-name not specified" ); + } + + if ( settingFieldName == null ) { + throw new IllegalStateException( "Setting constant field-name not specified" ); + } + + if ( publishedJavadocLink == null ) { + throw new IllegalStateException( "Setting javadoc link not specified" ); + } + + if ( asciidoc == null ) { + throw new IllegalStateException( "Setting comment not specified" ); + } + + return new SettingDescriptor( + name, + settingsClassName, + settingFieldName, + publishedJavadocLink, + asciidoc, + defaultValue, + apiNote, + since, + deprecated, + incubating + ); + } +} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocExtension.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocExtension.java index 2d99f71d5e..779ff12c03 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocExtension.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocExtension.java @@ -16,8 +16,6 @@ import org.gradle.api.file.RegularFileProperty; import org.gradle.api.provider.Property; import org.gradle.util.internal.ConfigureUtil; -import org.hibernate.orm.env.HibernateVersion; - import groovy.lang.Closure; /** @@ -30,6 +28,7 @@ public class SettingsDocExtension { private final DirectoryProperty javadocDirectory; private final Property publishedDocsUrl; + private final Property anchorNameBase; private final NamedDomainObjectContainer sections; private final RegularFileProperty outputFile; @@ -38,6 +37,7 @@ public class SettingsDocExtension { public SettingsDocExtension(Project project) { javadocDirectory = project.getObjects().directoryProperty(); publishedDocsUrl = project.getObjects().property( String.class ); + anchorNameBase = project.getObjects().property( String.class ); sections = project.getObjects().domainObjectContainer( SettingsDocSection.class, SettingsDocSection::create ); outputFile = project.getObjects().fileProperty(); @@ -62,6 +62,14 @@ public class SettingsDocExtension { return publishedDocsUrl; } + public Property getAnchorNameBase() { + return anchorNameBase; + } + + public void setAnchorNameBase(String base) { + anchorNameBase.set( base ); + } + /** * Configuration of the sections within the generated document */ diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocGenerationTask.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocGenerationTask.java index 21b2f62fb1..741eeb1a4e 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocGenerationTask.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocGenerationTask.java @@ -15,12 +15,14 @@ import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.provider.Property; import org.gradle.api.tasks.IgnoreEmptyDirectories; +import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputDirectory; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; import org.hibernate.orm.env.HibernateVersion; +import org.hibernate.orm.properties.jdk11.SettingsCollector; import static org.hibernate.orm.properties.SettingsDocumentationPlugin.TASK_GROUP_NAME; @@ -34,7 +36,7 @@ public class SettingsDocGenerationTask extends DefaultTask { private final DirectoryProperty javadocDirectory; private final Property publishedDocsUrl; - + private final Property anchorNameBase; private final NamedDomainObjectContainer sections; private final RegularFileProperty outputFile; @@ -53,6 +55,9 @@ public class SettingsDocGenerationTask extends DefaultTask { publishedDocsUrl = project.getObjects().property( String.class ); publishedDocsUrl.convention( dslExtension.getPublishedDocsUrl() ); + anchorNameBase = project.getObjects().property( String.class ); + anchorNameBase.convention( dslExtension.getAnchorNameBase() ); + sections = dslExtension.getSections(); outputFile = project.getObjects().fileProperty(); @@ -65,6 +70,16 @@ public class SettingsDocGenerationTask extends DefaultTask { return javadocDirectory; } + @Input + public Property getPublishedDocsUrl() { + return publishedDocsUrl; + } + + @Input + public Property getAnchorNameBase() { + return anchorNameBase; + } + @Nested public NamedDomainObjectContainer getSections() { return sections; @@ -83,6 +98,7 @@ public class SettingsDocGenerationTask extends DefaultTask { + "/javadocs/"; AsciiDocWriter.writeToFile( + anchorNameBase.get(), SettingsCollector.collectSettingDescriptors( javadocDirectory.get(), sections.getAsMap(), diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocSection.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocSection.java index d5feb078fe..9762f0d603 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocSection.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocSection.java @@ -6,23 +6,88 @@ */ package org.hibernate.orm.properties; +import java.util.ArrayList; import java.util.Comparator; +import java.util.List; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Internal; - -import static java.util.Comparator.comparing; +import org.gradle.api.tasks.Optional; /** * DSL extension for defining a section in the settings appendix in the User Guide. - *

- * Specifies the settings class to match, and identifies which module (by name) the - * settings class from. * * @author Steve Ebersole */ public class SettingsDocSection { - public static final Comparator BY_NAME = comparing( SettingsDocSection::getName ); + private final String name; + + private Integer explicitPosition; + private String summary; + private String description; + private List settingsClassNames = new ArrayList<>(); + + public SettingsDocSection(String name) { + this.name = name; + } + + private SettingsDocSection( + String name, + Integer explicitPosition) { + this.name = name; + this.explicitPosition = explicitPosition; + } + + @Internal + public String getName() { + return name; + } + + @Optional + @Input + public Integer getExplicitPosition() { + return explicitPosition; + } + + public void setExplicitPosition(Integer explicitPosition) { + this.explicitPosition = explicitPosition; + } + + @Input + public List getSettingsClassNames() { + return settingsClassNames; + } + + public void setSettingsClassNames(List settingsClassNames) { + this.settingsClassNames = settingsClassNames; + } + + public void settingsClassName(String name) { + settingsClassNames.add( name ); + } + + @Input + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + @Input + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String toString() { + return "SettingsDocSection(" + name + " [" + explicitPosition + "])"; + } /** * Factory for SettingsDocSection instances @@ -31,36 +96,22 @@ public class SettingsDocSection { return new SettingsDocSection( name ); } - private final String name; + private static final Comparator nullsLastInComparator = Comparator.nullsLast( Integer::compare ); + private static final Comparator nameComparator = Comparator.comparing( SettingsDocSection::getName ); - // todo : do we ever care about multiple settings-classes for a single project? - private String projectPath; - private String settingsClassName; + public static int compare(SettingsDocSection section1, SettingsDocSection section2) { + // todo (settings-doc) : add support for negative-as-last? + // - as a means to easily sort "less used" values at the end (EnvironmentSettings, etc) - public SettingsDocSection(String name) { - this.name = name; - } + final Integer explicitPosition1 = section1.getExplicitPosition(); + final Integer explicitPosition2 = section2.getExplicitPosition(); - @Internal - public String getName() { - return name; - } + final int positionComparison = nullsLastInComparator.compare( explicitPosition1, explicitPosition2 ); - @Input - public String getProjectPath() { - return projectPath; - } + if ( positionComparison != 0 ) { + return positionComparison; + } - public void setProjectPath(String projectPath) { - this.projectPath = projectPath; - } - - @Input - public String getSettingsClassName() { - return settingsClassName; - } - - public void setSettingsClassName(String settingsClassName) { - this.settingsClassName = settingsClassName; + return nameComparator.compare( section1, section2 ); } } diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocumentationPlugin.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocumentationPlugin.java index 5b08a1cee0..8659503844 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocumentationPlugin.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsDocumentationPlugin.java @@ -10,7 +10,6 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; import org.hibernate.orm.env.EnvironmentProjectPlugin; -import org.hibernate.orm.env.HibernateVersion; import static org.hibernate.orm.properties.SettingsDocExtension.EXTENSION_NAME; import static org.hibernate.orm.properties.SettingsDocGenerationTask.TASK_NAME; diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/Utils.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/Utils.java index dace41a8f7..61a7994b7c 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/Utils.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/Utils.java @@ -7,6 +7,12 @@ package org.hibernate.orm.properties; import java.io.File; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; /** * @author Steve Ebersole @@ -25,4 +31,12 @@ public class Utils { public static String packagePrefix(String className) { return className.substring( 0, className.lastIndexOf( '.' ) ); } + + public static Map> createResultMap(Map sections) { + final TreeMap> map = new TreeMap<>( SettingsDocSection::compare ); + sections.forEach( (name, descriptor) -> { + map.put( descriptor, new TreeSet<>( SettingDescriptorComparator.INSTANCE ) ); + } ); + return map; + } } diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/DomToAsciidocConverter.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/DomToAsciidocConverter.java new file mode 100644 index 0000000000..c768536928 --- /dev/null +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/DomToAsciidocConverter.java @@ -0,0 +1,176 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.orm.properties.jdk11; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +import org.jsoup.nodes.Element; +import org.jsoup.nodes.Node; +import org.jsoup.nodes.TextNode; +import org.jsoup.select.Elements; + +/** + * @author Steve Ebersole + */ +class DomToAsciidocConverter { + public static String convert(Elements elements) { + final DomToAsciidocConverter converter = new DomToAsciidocConverter(); + return converter.convertInternal( elements ); + } + + public static String convert(Element element) { + final DomToAsciidocConverter converter = new DomToAsciidocConverter(); + return converter.convertInternal( element ); + } + + private final Map> elementVisitorsByTag = new HashMap<>(); + private final StringBuilder converted = new StringBuilder(); + + public DomToAsciidocConverter() { + elementVisitorsByTag.put( "a", this::visitLink ); + elementVisitorsByTag.put( "span", this::visitSpan ); + elementVisitorsByTag.put( "ul", this::visitUl ); + elementVisitorsByTag.put( "ol", this::visitUl ); + elementVisitorsByTag.put( "li", this::visitLi ); + elementVisitorsByTag.put( "b", this::visitBold ); + elementVisitorsByTag.put( "strong", this::visitBold ); + elementVisitorsByTag.put( "em", this::visitBold ); + elementVisitorsByTag.put( "code", this::visitCode ); + elementVisitorsByTag.put( "p", this::visitDiv ); + elementVisitorsByTag.put( "div", this::visitDiv ); + elementVisitorsByTag.put( "dl", this::visitDiv ); + elementVisitorsByTag.put( "dd", this::visitDiv ); + } + + private String convertInternal(Elements elements) { + for ( Element element : elements ) { + visitElement( element ); + } + return converted.toString(); + } + + private String convertInternal(Element element) { + visitElement( element ); + return converted.toString(); + } + + private void visitNode(Node node) { + // We know about 2 types of nodes that we care about: + // 1. Element -- means that it is some tag, + // so we will defer the decision what to do about it to the visitElement. + // 2. TextNode -- simple text that we'll just add to the converted result. + // + // If we encounter something else -- let's fail, + // so we can investigate what new element type it is and decide what to do about it. + if ( node instanceof Element ) { + visitElement( ( (Element) node ) ); + } + else if ( node instanceof TextNode ) { + visitTextNode( (TextNode) node ); + } + else { + visitUnknownNode( node ); + } + } + + private void visitElement(Element element) { + String tag = element.tagName(); + + Consumer visitor = elementVisitorsByTag.get( tag ); + if ( visitor == null ) { + // If we encounter an element that we are not handling -- + // we want to fail as the result might be missing some details: + throw new IllegalStateException( "Unknown element: " + element ); + } + + visitor.accept( element ); + } + + private void visitDiv(Element div) { + if ( converted.length() != 0 ) { + converted.append( "\n+\n" ); + } + for ( Node childNode : div.childNodes() ) { + visitNode( childNode ); + } + converted.append( '\n' ); + } + + private void visitCode(Element code) { + converted.append( "`" ); + for ( Node childNode : code.childNodes() ) { + visitNode( childNode ); + } + converted.append( "`" ); + } + + private void visitBold(Element bold) { + converted.append( "**" ); + for ( Node childNode : bold.childNodes() ) { + visitNode( childNode ); + } + converted.append( "**" ); + } + + private void visitLi(Element li) { + converted.append( "\n * " ); + for ( Node childNode : li.childNodes() ) { + visitNode( childNode ); + } + } + + private void visitUl(Element ul) { + if ( converted.lastIndexOf( "\n" ) != converted.length() - 1 ) { + converted.append( '\n' ); + } + converted.append( "+\n" ); + for ( Node childNode : ul.childNodes() ) { + visitNode( childNode ); + } + } + + private void visitSpan(Element span) { + // If it is a label for deprecation, let's make it bold to stand out: + boolean deprecatedLabel = span.hasClass( "deprecatedLabel" ); + if ( deprecatedLabel ) { + converted.append( "**" ); + } + for ( Node childNode : span.childNodes() ) { + visitNode( childNode ); + } + if ( deprecatedLabel ) { + converted.append( "**" ); + } + } + + private void visitLink(Element link) { + converted.append( "link:" ) + .append( link.attr( "href" ) ) + .append( '[' ); + for ( Node childNode : link.childNodes() ) { + visitNode( childNode ); + } + converted.append( ']' ); + } + + private void visitTextNode(TextNode node) { + if ( converted.lastIndexOf( "+\n" ) == converted.length() - "+\n".length() ) { + // if it's a start of a paragraph - remove any leading spaces: + converted.append( ( node ).text().replaceAll( "^\\s+", "" ) ); + } + else { + converted.append( ( node ).text() ); + } + } + + private void visitUnknownNode(Node node) { + // if we encounter a node that we are not handling - we want to fail as the result might be missing some details: + throw new IllegalStateException( "Unknown node: " + node ); + } +} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/SettingsCollector.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/SettingsCollector.java new file mode 100644 index 0000000000..0115a2c06a --- /dev/null +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk11/SettingsCollector.java @@ -0,0 +1,359 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.orm.properties.jdk11; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.SortedSet; + +import org.gradle.api.file.Directory; + +import org.hibernate.orm.properties.SettingDescriptor; +import org.hibernate.orm.properties.SettingWorkingDetails; +import org.hibernate.orm.properties.SettingsDocSection; +import org.hibernate.orm.properties.Utils; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import static org.hibernate.orm.properties.Utils.packagePrefix; +import static org.hibernate.orm.properties.Utils.withoutPackagePrefix; + + +/** + * Processes Javadoc into SettingDescriptor based on the JDK 11 javadoc format + * + * @author Marko Bekhta + * @author Steve Ebersole + */ +public class SettingsCollector { + + public static Map> collectSettingDescriptors( + Directory javadocDirectory, + Map sections, + String publishedJavadocsUrl) { + return collectSettingDescriptors( javadocDirectory.getAsFile(), sections, publishedJavadocsUrl ); + } + + + public static Map> collectSettingDescriptors( + File javadocDirectory, + Map sections, + String publishedJavadocsUrl) { + final Map> result = Utils.createResultMap( sections ); + + // Load the constant-values.html file with Jsoup and start processing it + final Document constantValuesDocument = loadConstants( javadocDirectory ); + + // For each Element in constant-values.html... + for ( Element table : constantValuesDocument.select( "table.constantsSummary" ) ) { + // e.g. org.hibernate.cfg.JdbcSettings + final String className = table.selectFirst( "caption" ).text(); + + // find the doc section descriptor defined for this class, if one + final SettingsDocSection docSection = findMatchingDocSection( className, sections ); + if ( docSection == null ) { + // does not match any defined sections, skip it + continue; + } + + // todo (settings-doc) : consider extracting all @see tags and grabbing ones that refer to other "setting field" + // and ultimately render "cross links" - i.e. `@see JdbcSettings#JAKARTA_JDBC_URL`. + // - or even handling all "setting constant" links this way + // - these are contained as notes in the Javadoc. + // - this would require a second pass though after all "setting details" have bee processed. + // - we don't need this until ^^ + //final Map settingWorkingDetailsMap = new HashMap<>(); + + // Load the Javadoc HTML for the constants class, e.g. org.hibernate.cfg.JdbcSettings + final Document constantsClassDocument = loadClassJavadoc( className, javadocDirectory ); + + // go through constants from constant-values.html + for ( Element row : table.select( "tr" ) ) { + if ( row.hasClass( "altColor" ) || row.hasClass( "rowColor" ) ) { + // + final String constantValue = row.selectFirst( ".colLast" ).text(); + final String settingName = stripQuotes( constantValue ); + + // locate the blockList for the field from the constants class Javadoc + // + // + // + // + //
    + //
  • + //

    DIALECT

    + // .. + //
    {COMMENT}
    + //
    + // + //
    + //
  • + //
+ final Element fieldJavadocBlockList = constantsClassDocument.selectFirst( "#" + simpleFieldName + " + ul li.blockList" ); + + if ( fieldJavadocBlockList == null || isUselessJavadoc( fieldJavadocBlockList ) ) { + System.out.println( className + "#" + simpleFieldName + " defined no Javadoc - ignoring." ); + continue; + } + + final SettingWorkingDetails settingWorkingDetails = new SettingWorkingDetails( + settingName, + className, + simpleFieldName, + Utils.fieldJavadocLink( + publishedJavadocsUrl, + className, + simpleFieldName + ) + ); + + applyMetadata( className, publishedJavadocsUrl, settingWorkingDetails, fieldJavadocBlockList ); + + final Elements javadocsToConvert = cleanupFieldJavadocElement( fieldJavadocBlockList, className, publishedJavadocsUrl ); + final SettingDescriptor settingDescriptor = settingWorkingDetails.buildDescriptor( + DomToAsciidocConverter.convert( javadocsToConvert ) + ); + + final SortedSet docSectionSettings = result.get( docSection ); + docSectionSettings.add( settingDescriptor ); + } + } + } + + return result; + } + + public static Document loadConstants(File javadocDirectory) { + try { + final File constantValuesFile = new File( javadocDirectory, "constant-values.html" ); + return Jsoup.parse( constantValuesFile ); + } + catch (IOException e) { + throw new IllegalStateException( "Unable to access javadocs `constant-values.html`", e ); + } + } + + private static Document loadClassJavadoc(String enclosingClass, File javadocDirectory) { + final String classJavadocFileName = enclosingClass.replace( ".", File.separator ) + ".html"; + final File classJavadocFile = new File( javadocDirectory, classJavadocFileName ); + + try { + return Jsoup.parse( classJavadocFile ); + } + catch (IOException e) { + throw new RuntimeException( "Unable to access javadocs for " + enclosingClass, e ); + } + } + + /** + * @param fieldJavadocElement The element to inspect if it has some valuable documentation. + * @return {@code true} if no Javadoc was written for this field; {@code false} otherwise. + */ + private static boolean isUselessJavadoc(Element fieldJavadocElement) { + return fieldJavadocElement.selectFirst( "div.block" ) == null; + } + + private static void applyMetadata( + String className, + String publishedJavadocsUrl, + SettingWorkingDetails settingDetails, + Element fieldJavadocElement) { + processNotes( + fieldJavadocElement, + (name, content) -> { + switch ( name ) { + case "Default Value:": { + fixUrls( className, publishedJavadocsUrl, content ); + final String defaultValueText = DomToAsciidocConverter.convert( content ); + settingDetails.setDefaultValue( defaultValueText ); + break; + } + case "API Note:": { + settingDetails.setApiNote( content.text() ); + break; + } + case "Since:": { + settingDetails.setSince( content.text() ); + break; + } + } + } + ); + + settingDetails.setIncubating( interpretIncubation( fieldJavadocElement ) ); + settingDetails.setDeprecated( interpretDeprecation( fieldJavadocElement ) ); + } + + private static SettingsDocSection findMatchingDocSection( + String className, + Map sections) { + for ( Map.Entry entry : sections.entrySet() ) { + if ( entry.getValue().getSettingsClassNames().contains( className ) ) { + return entry.getValue(); + } + } + return null; + } + + private static String stripQuotes(String value) { + if ( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) { + return value.substring( 1, value.length() - 1 ); + } + return value; + } + + @FunctionalInterface + private interface NoteConsumer { + void consumeNote(String name, Element content); + } + + private static void processNotes( + Element fieldJavadocElement, + NoteConsumer noteConsumer) { + final Element notesElement = fieldJavadocElement.selectFirst( "dl" ); + if ( notesElement == null ) { + return; + } + + // should be a list of alternating
and
elements. + final Elements notesChildren = notesElement.children(); + for ( int i = 0; i < notesChildren.size(); i+=2 ) { + final Element dtNode = notesChildren.get( i ); + if ( !dtNode.tagName().equals( "dt" ) ) { + throw new RuntimeException( "Unexpected Javadoc format" ); + } + + final Element ddNode = notesChildren.get( i+1 ); + if ( !ddNode.tagName().equals( "dd" ) ) { + throw new RuntimeException( "Unexpected Javadoc format" ); + } + + noteConsumer.consumeNote( dtNode.text().trim(), ddNode ); + } + } + + private static boolean interpretIncubation(Element fieldJavadocElement) { + final Element incubatingMarkerElement = fieldJavadocElement.selectFirst( "[href*=.Incubating.html]" ); + return incubatingMarkerElement != null; + } + + private static boolean interpretDeprecation(Element fieldJavadocElement) { + // A setting is considered deprecated with either `@Deprecated` + final Element deprecationDiv = fieldJavadocElement.selectFirst( ".deprecationBlock" ); + // presence of this
indicates the member is deprecated + if ( deprecationDiv != null ) { + return true; + } + + // or `@Remove` + final Element removeMarkerElement = fieldJavadocElement.selectFirst( "[href*=.Remove.html]" ); + if ( removeMarkerElement != null ) { + return true; + } + + return false; + } + + private static Elements cleanupFieldJavadocElement( + Element fieldJavadocElement, + String className, + String publishedJavadocsUrl) { + // Before proceeding let's make sure that the javadoc structure is the one that we expect: + if ( !isValidFieldJavadocStructure( fieldJavadocElement ) ) { + throw new IllegalStateException( + "Javadoc's DOM doesn't match the expected structure. " + + "This may lead to unexpected results in rendered configuration properties in the User Guide." + ); + } + + fixUrls( className, publishedJavadocsUrl, fieldJavadocElement ); + + final Elements usefulDocsPart = new Elements(); + + // We want to take the javadoc comment block... + final Element javadocComment = fieldJavadocElement.selectFirst( "div.block" ); + usefulDocsPart.add( javadocComment ); + + return usefulDocsPart; + } + + /** + * Any ORM links will be relative, and we want to prepend them with the {@code publishedJavadocsUrl} + * so that they are usable when the doc is published. + * Any external links should have a {@code externalLink} or {@code external-link} CSS class, we want to keep them unchanged. + *

+ * NOTE: this method modifies the parsed DOM. + */ + private static void fixUrls( + String className, + String publishedJavadocsUrl, + Element fieldJavadocElement) { + for ( Element link : fieldJavadocElement.getElementsByTag( "a" ) ) { + // only update links if they are not external: + if ( !isExternalLink( link ) ) { + String href = link.attr( "href" ); + if ( href.startsWith( "#" ) ) { + href = withoutPackagePrefix( className ) + ".html" + href; + } + String packagePath = packagePrefix( className ).replace( ".", File.separator ); + href = publishedJavadocsUrl + packagePath + "/" + href; + link.attr( "href", href ); + } + } + } + + private static boolean isExternalLink(Element link) { + String href = link.attr( "href" ); + return link.hasClass( "externalLink" ) + || link.hasClass( "external-link" ) + || href != null && href.startsWith( "http" ); + } + + private static boolean isValidFieldJavadocStructure(Element fieldJavadocElement) { + // Field's DOM sub-structure that we are expecting should be: + // + //

    + //
  • + //

    DIALECT

    + //
    +		//         
    +		//     
    +		//   
  • + //
+ + if ( !"li".equals( fieldJavadocElement.tagName() ) ) { + return false; + } + + if ( !fieldJavadocElement.hasClass( "blockList" ) ) { + return false; + } + + if ( fieldJavadocElement.selectFirst( "div.block" ) == null + && fieldJavadocElement.selectFirst( "dl" ) == null + && fieldJavadocElement.selectFirst( "pre" ) == null ) { + return false; + } + + return true; + } + +} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsCollector.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk17/JavadocToAsciidocConverter.java similarity index 54% rename from local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsCollector.java rename to local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk17/JavadocToAsciidocConverter.java index 706a762e0c..def21e395c 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/properties/SettingsCollector.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk17/JavadocToAsciidocConverter.java @@ -4,23 +4,15 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. */ -package org.hibernate.orm.properties; +package org.hibernate.orm.properties.jdk17; import java.io.File; -import java.io.IOException; import java.util.HashMap; import java.util.Map; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; import java.util.function.Consumer; -import org.gradle.api.file.Directory; -import org.gradle.api.file.RegularFile; +import org.hibernate.orm.properties.Utils; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import org.jsoup.nodes.TextNode; @@ -30,178 +22,9 @@ import static org.hibernate.orm.properties.Utils.packagePrefix; import static org.hibernate.orm.properties.Utils.withoutPackagePrefix; /** - * @author Marko Bekhta * @author Steve Ebersole */ -public class SettingsCollector { - - public static SortedMap> collectSettingDescriptors( - Directory javadocDirectory, - Map sections, - String publishedJavadocsUrl) { - final SortedMap> result = new TreeMap<>( SettingsDocSection.BY_NAME ); - - // Load the constant-values.html file with Jsoup and start processing it - final Document constantValuesJson = loadConstants( javadocDirectory ); - final Elements blockLists = constantValuesJson.select( "ul.block-list" ); - final Map> fieldJavadocsByClass = new HashMap<>(); - for ( int bl = 0; bl < blockLists.size(); bl++ ) { - final Element blockList = blockLists.get( bl ); - final String className = blockList.selectFirst( "span" ).text(); - - // find the doc section descriptor defined for this class, if one - final SettingsDocSection docSection = findMatchingDocSection( className, sections ); - if ( docSection == null ) { - // does not match any defined sections, skip it - continue; - } - - final SortedSet docSectionSettings = findSettingDescriptors( docSection, result ); - final Map classFieldJavadocs = extractClassFieldJavadocs( className, javadocDirectory, fieldJavadocsByClass ); - - final Element tableDiv = blockList.selectFirst( ".summary-table" ); - final Elements constantFqnColumns = tableDiv.select( ".col-first" ); - final Elements constantValueColumns = tableDiv.select( ".col-last" ); - - for ( int c = 0; c < constantFqnColumns.size(); c++ ) { - final Element constantFqnColumn = constantFqnColumns.get( c ); - if ( constantFqnColumn.hasClass( "table-header" ) ) { - continue; - } - - final String constantFqn = constantFqnColumn.selectFirst( "code" ).id(); - final String constantValue = constantValueColumns.get( c ).selectFirst( "code" ).text(); - - // locate the field javadoc from `classFieldJavadocs`. - // that map is keyed by the simple name of the field, so strip the - // package and class name from `constantFqn` to do the look-up - // - // NOTE : there may be no Javadoc, in which case the Element will be null; - // there is literally no such div in these cases - final String simpleFieldName = constantFqn.substring( constantFqn.lastIndexOf( '.' ) + 1 ); - final Element fieldJavadocElement = classFieldJavadocs.get( simpleFieldName ); - - if ( fieldJavadocElement == null || isUselessJavadoc( fieldJavadocElement ) ) { - System.out.println( "There was no javadoc found for " + className + "#" + simpleFieldName - + ". Ignoring this setting." ); - continue; - } - - final SettingDescriptor settingDescriptor = new SettingDescriptor( - stripQuotes( constantValue ), - className, - simpleFieldName, - convertFieldJavadocHtmlToAsciidoc( - fieldJavadocElement, - className, - simpleFieldName, - publishedJavadocsUrl - ), - interpretDeprecation( fieldJavadocElement ), - interpretIncubation( fieldJavadocElement ) - ); - docSectionSettings.add( settingDescriptor ); - } - } - - return result; - } - - public static Document loadConstants(Directory javadocDirectory) { - try { - final File constantValuesFile = javadocDirectory.file( "constant-values.html" ).getAsFile(); - return Jsoup.parse( constantValuesFile ); - } - catch (IOException e) { - throw new IllegalStateException( "Unable to access javadocs `constant-values.html`", e ); - } - } - - private static SettingsDocSection findMatchingDocSection( - String className, - Map sections) { - for ( Map.Entry entry : sections.entrySet() ) { - if ( entry.getValue().getSettingsClassName().equals( className ) ) { - return entry.getValue(); - } - } - return null; - } - - private static SortedSet findSettingDescriptors( - SettingsDocSection docSection, - SortedMap> map) { - final SortedSet existing = map.get( docSection ); - if ( existing != null ) { - return existing; - } - - final SortedSet created = new TreeSet<>( SettingDescriptor.BY_NAME ); - map.put( docSection, created ); - return created; - } - - private static Map extractClassFieldJavadocs( - String className, - Directory javadocDirectory, - Map> fieldJavadocsByClass) { - final Map existing = fieldJavadocsByClass.get( className ); - if ( existing != null ) { - return existing; - } - - final Map result = new HashMap<>(); - - final Document document = loadClassJavadoc( className, javadocDirectory ); - final Elements fieldDetailSections = document.select( "section.detail" ); - for ( Element fieldDetailSection : fieldDetailSections ) { - final String fieldName = fieldDetailSection.id(); - result.put( fieldName, fieldDetailSection ); - } - - return result; - } - - private static Document loadClassJavadoc(String enclosingClass, Directory javadocDirectory) { - final String classJavadocFileName = enclosingClass.replace( ".", File.separator ) + ".html"; - final RegularFile classJavadocFile = javadocDirectory.file( classJavadocFileName ); - - try { - return Jsoup.parse( classJavadocFile.getAsFile() ); - } - catch (IOException e) { - throw new RuntimeException( "Unable to access javadocs for " + enclosingClass, e ); - } - } - - private static String stripQuotes(String value) { - if ( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) { - return value.substring( 1, value.length() - 1 ); - } - return value; - } - - private static boolean interpretDeprecation(Element fieldJavadocElement) { - // A setting is considered deprecated with either `@Deprecated` - final Element deprecationDiv = fieldJavadocElement.selectFirst( ".deprecation-block" ); - // presence of this
indicates the member is deprecated - if ( deprecationDiv != null ) { - return true; - } - - // or `@Remove` - final Element removeMarkerElement = fieldJavadocElement.selectFirst( "[href*=Remove.html]" ); - if ( removeMarkerElement != null ) { - return true; - } - - return false; - } - - private static boolean interpretIncubation(Element fieldJavadocElement) { - final Element incubatingMarkerElement = fieldJavadocElement.selectFirst( "[href*=Incubating.html]" ); - return incubatingMarkerElement != null; - } +public class JavadocToAsciidocConverter { /** * Convert the DOM representation of the field Javadoc to Asciidoc format @@ -211,7 +34,7 @@ public class SettingsCollector { * @param simpleFieldName The name of the field defining the setting (relative to {@code className}) * @param publishedJavadocsUrl The (versioned) URL to Javadocs on the doc server */ - private static String convertFieldJavadocHtmlToAsciidoc( + public static String convertFieldJavadocHtmlToAsciidoc( Element fieldJavadocElement, String className, String simpleFieldName, @@ -222,13 +45,13 @@ public class SettingsCollector { } private static Elements cleanupFieldJavadocElement(Element fieldJavadocElement, - String className, - String simpleFieldName, - String publishedJavadocsUrl) { + String className, + String simpleFieldName, + String publishedJavadocsUrl) { // Before proceeding let's make sure that the javadoc structure is the one that we expect: if ( !isValidFieldJavadocStructure( fieldJavadocElement ) ) { throw new IllegalStateException( "Javadoc's DOM doesn't match the expected structure. " + - "This may lead to unexpected results in rendered configuration properties in the User Guide." ); + "This may lead to unexpected results in rendered configuration properties in the User Guide." ); } fixUrls( className, publishedJavadocsUrl, fieldJavadocElement ); @@ -240,12 +63,12 @@ public class SettingsCollector { usefulDocsPart.add( actualJavadocs ); } usefulDocsPart.add( new Element( "div" ) - .appendChild( new Element( "b" ).text( "See: " ) ) - .appendChild( new Element( "a" ) - .attr( - "href", - Utils.fieldJavadocLink( publishedJavadocsUrl, className, simpleFieldName ) - ).text( Utils.withoutPackagePrefix( className ) + "." + simpleFieldName ) ) ); + .appendChild( new Element( "b" ).text( "See: " ) ) + .appendChild( new Element( "a" ) + .attr( + "href", + Utils.fieldJavadocLink( publishedJavadocsUrl, className, simpleFieldName ) + ).text( Utils.withoutPackagePrefix( className ) + "." + simpleFieldName ) ) ); return usefulDocsPart; } @@ -258,8 +81,8 @@ public class SettingsCollector { * NOTE: this method modifies the parsed DOM. */ private static void fixUrls(String className, - String publishedJavadocsUrl, - Element fieldJavadocElement) { + String publishedJavadocsUrl, + Element fieldJavadocElement) { for ( Element link : fieldJavadocElement.getElementsByTag( "a" ) ) { // only update links if they are not external: if ( !isExternalLink( link ) ) { @@ -307,14 +130,6 @@ public class SettingsCollector { return true; } - /** - * @param fieldJavadocElement The element to inspect if it has some valuable documentation. - * @return {@code true} if no Javadoc was written for this field; {@false otherwise}. - */ - private static boolean isUselessJavadoc(Element fieldJavadocElement) { - return fieldJavadocElement.selectFirst( "div.block" ) == null; - } - private static class DomToAsciidocConverter { private final Map> elementVisitorsByTag = new HashMap<>(); private final StringBuilder converted = new StringBuilder(); diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk17/SettingsCollector.java b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk17/SettingsCollector.java new file mode 100644 index 0000000000..e5bacf1cd1 --- /dev/null +++ b/local-build-plugins/src/main/java/org/hibernate/orm/properties/jdk17/SettingsCollector.java @@ -0,0 +1,270 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.orm.properties.jdk17; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; + +import org.gradle.api.file.Directory; + +import org.hibernate.orm.properties.SettingDescriptor; +import org.hibernate.orm.properties.SettingWorkingDetails; +import org.hibernate.orm.properties.SettingsDocSection; +import org.hibernate.orm.properties.Utils; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import static org.hibernate.orm.properties.jdk17.JavadocToAsciidocConverter.convertFieldJavadocHtmlToAsciidoc; + +/** + * @author Marko Bekhta + * @author Steve Ebersole + */ +public class SettingsCollector { + + public static Map> collectSettingDescriptors( + Directory javadocDirectory, + Map sections, + String publishedJavadocsUrl) { + return collectSettingDescriptors( javadocDirectory.getAsFile(), sections, publishedJavadocsUrl ); + } + + public static Map> collectSettingDescriptors( + File javadocDirectory, + Map sections, + String publishedJavadocsUrl) { + final Map> result = Utils.createResultMap( sections ); + + // Load the constant-values.html file with Jsoup and start processing it + final Document constantValuesJson = loadConstants( javadocDirectory ); + + final Elements captionClassDivs = constantValuesJson.select( "div.caption" ); + for ( Element captionClassDiv : captionClassDivs ) { + final String className = captionClassDiv.selectFirst( "span" ).text(); + + // find the doc section descriptor defined for this class, if one + final SettingsDocSection docSection = findMatchingDocSection( className, sections ); + if ( docSection == null ) { + // does not match any defined sections, skip it + continue; + } + + // find the summary-table div that contains the constant->value mappings for class-name + final Element captionClassDivParent = captionClassDiv.parent(); + final Element tableDiv = captionClassDivParent.selectFirst( ".summary-table" ); + final Elements constantFqnColumns = tableDiv.select( ".col-first" ); + final Elements constantValueColumns = tableDiv.select( ".col-last" ); + + // extract the Javadoc elements for each field on class-name + final Map classFieldJavadocs = extractClassFieldJavadocs( className, javadocDirectory ); + + // todo (settings-doc) : consider extracting all @see tags and grabbing ones that refer to other "setting field" + // and ultimately render "cross links" - i.e. `@see JdbcSettings#JAKARTA_JDBC_URL`. + // these are contained as notes in the Javadoc. + // this would require a second pass though after all "setting details" have bee processed. + // for now, we don't need this + //final Map settingWorkingDetailsMap = new HashMap<>(); + + for ( int c = 0; c < constantFqnColumns.size(); c++ ) { + final Element constantFqnColumn = constantFqnColumns.get( c ); + if ( constantFqnColumn.hasClass( "table-header" ) ) { + continue; + } + + final String constantFqn = constantFqnColumn.selectFirst( "code" ).id(); + final String constantValue = constantValueColumns.get( c ).selectFirst( "code" ).text(); + + // locate the field javadoc from `classFieldJavadocs`. + // that map is keyed by the simple name of the field, so strip the + // package and class name from `constantFqn` to do the look-up + // + // NOTE : there may be no Javadoc, in which case the Element will be null; + // there is literally no such div in these cases + final String simpleFieldName = constantFqn.substring( constantFqn.lastIndexOf( '.' ) + 1 ); + final Element fieldJavadocElement = classFieldJavadocs.get( simpleFieldName ); + + if ( fieldJavadocElement == null || isUselessJavadoc( fieldJavadocElement ) ) { + System.out.println( className + "#" + simpleFieldName + " defined no Javadoc - ignoring." ); + continue; + } + + final String settingName = stripQuotes( constantValue ); + final SettingWorkingDetails settingWorkingDetails = new SettingWorkingDetails( + settingName, + className, + simpleFieldName, + Utils.fieldJavadocLink( + publishedJavadocsUrl, + className, + simpleFieldName + ) + ); + applyMetadata( settingWorkingDetails, fieldJavadocElement ); + // todo (settings-doc) : here is where we'd add to the `settingWorkingDetailsMap` + //settingWorkingDetailsMap.put( .., settingWorkingDetails ); + // for now though, just generate the SettingDescriptor + final SettingDescriptor settingDescriptor = settingWorkingDetails.buildDescriptor( + convertFieldJavadocHtmlToAsciidoc( + fieldJavadocElement, + className, + simpleFieldName, + publishedJavadocsUrl + ) + ); + + final SortedSet docSectionSettings = result.get( docSection ); + docSectionSettings.add( settingDescriptor ); + } + } + + return result; + } + + /** + * @param fieldJavadocElement The element to inspect if it has some valuable documentation. + * @return {@code true} if no Javadoc was written for this field; {@code false} otherwise. + */ + private static boolean isUselessJavadoc(Element fieldJavadocElement) { + return fieldJavadocElement.selectFirst( "div.block" ) == null; + } + + private static void applyMetadata(SettingWorkingDetails settingDetails, Element fieldJavadocElement) { + processNotes( + fieldJavadocElement, + (name, content) -> { + switch ( name ) { + case "Default Value:": { + settingDetails.setDefaultValue( content ); + break; + } + case "API Note:": { + settingDetails.setApiNote( content ); + break; + } + case "Since:": { + settingDetails.setSince( content ); + break; + } + } + } + ); + settingDetails.setIncubating( interpretIncubation( fieldJavadocElement ) ); + settingDetails.setDeprecated( interpretDeprecation( fieldJavadocElement ) ); + } + + public static Document loadConstants(File javadocDirectory) { + try { + final File constantValuesFile = new File( javadocDirectory, "constant-values.html" ); + return Jsoup.parse( constantValuesFile ); + } + catch (IOException e) { + throw new IllegalStateException( "Unable to access javadocs `constant-values.html`", e ); + } + } + + private static SettingsDocSection findMatchingDocSection( + String className, + Map sections) { + for ( Map.Entry entry : sections.entrySet() ) { + if ( entry.getValue().getSettingsClassNames().contains( className ) ) { + return entry.getValue(); + } + } + return null; + } + + private static Map extractClassFieldJavadocs(String className, File javadocDirectory) { + final Map result = new HashMap<>(); + + final Document document = loadClassJavadoc( className, javadocDirectory ); + final Elements fieldDetailSections = document.select( "section.detail" ); + for ( Element fieldDetailSection : fieldDetailSections ) { + final String fieldName = fieldDetailSection.id(); + result.put( fieldName, fieldDetailSection ); + } + + return result; + } + + private static Document loadClassJavadoc(String enclosingClass, File javadocDirectory) { + final String classJavadocFileName = enclosingClass.replace( ".", File.separator ) + ".html"; + final File classJavadocFile = new File( javadocDirectory, classJavadocFileName ); + + try { + return Jsoup.parse( classJavadocFile ); + } + catch (IOException e) { + throw new RuntimeException( "Unable to access javadocs for " + enclosingClass, e ); + } + } + + private static String stripQuotes(String value) { + if ( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) { + return value.substring( 1, value.length() - 1 ); + } + return value; + } + + @FunctionalInterface + private interface NoteConsumer { + void consumeNote(String name, String content); + } + + private static void processNotes( + Element fieldJavadocElement, + NoteConsumer noteConsumer) { + final Element notesElement = fieldJavadocElement.selectFirst( "dl.notes" ); + if ( notesElement == null ) { + return; + } + + // should be a list of alternating
and
elements. + final Elements notesChildren = notesElement.children(); + for ( int i = 0; i < notesChildren.size(); i+=2 ) { + final Element dtNode = notesChildren.get( i ); + if ( !dtNode.tagName().equals( "dt" ) ) { + throw new RuntimeException( "Unexpected Javadoc format" ); + } + + final Element ddNode = notesChildren.get( i+1 ); + if ( !ddNode.tagName().equals( "dd" ) ) { + throw new RuntimeException( "Unexpected Javadoc format" ); + } + + noteConsumer.consumeNote( dtNode.text().trim(), ddNode.text().trim() ); + } + } + + private static boolean interpretIncubation(Element fieldJavadocElement) { + final Element incubatingMarkerElement = fieldJavadocElement.selectFirst( "[href*=.Incubating.html]" ); + return incubatingMarkerElement != null; + } + + private static boolean interpretDeprecation(Element fieldJavadocElement) { + // A setting is considered deprecated with either `@Deprecated` + final Element deprecationDiv = fieldJavadocElement.selectFirst( ".deprecation-block" ); + // presence of this
indicates the member is deprecated + if ( deprecationDiv != null ) { + return true; + } + + // or `@Remove` + final Element removeMarkerElement = fieldJavadocElement.selectFirst( "[href*=.Remove.html]" ); + if ( removeMarkerElement != null ) { + return true; + } + + return false; + } + +} diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/toolchains/JavaModulePlugin.java b/local-build-plugins/src/main/java/org/hibernate/orm/toolchains/JavaModulePlugin.java index 22dde0ae6a..e197951b8d 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/toolchains/JavaModulePlugin.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/toolchains/JavaModulePlugin.java @@ -64,8 +64,8 @@ public class JavaModulePlugin implements Plugin { javaPluginExtension.getToolchain().getLanguageVersion().set( jdkVersionsConfig.getMainCompileVersion() ); configureCompileTasks( project ); - configureJavadocTasks( project ); configureTestTasks( project ); + configureJavadocTasks( project, mainSourceSet ); configureCompileTask( mainCompileTask, jdkVersionsConfig.getMainReleaseVersion() ); configureCompileTask( testCompileTask, jdkVersionsConfig.getTestReleaseVersion() ); @@ -117,24 +117,6 @@ public class JavaModulePlugin implements Plugin { } ); } - private void configureJavadocTasks(Project project) { - project.getTasks().withType( Javadoc.class ).configureEach( new Action() { - @Override - public void execute(Javadoc javadocTask) { - javadocTask.getOptions().setJFlags( javadocFlags( project ) ); - javadocTask.doFirst( new Action() { - @Override - public void execute(Task task) { - project.getLogger().lifecycle( - "Generating javadoc with '{}}'", - javadocTask.getJavadocTool().get().getMetadata().getInstallationPath() - ); - } - } ); - } - } ); - } - private void configureTestTasks(Project project) { project.getTasks().withType( Test.class ).configureEach( new Action() { @Override @@ -166,6 +148,21 @@ public class JavaModulePlugin implements Plugin { } ); } + private void configureJavadocTasks(Project project, SourceSet mainSourceSet) { + project.getTasks().named( mainSourceSet.getJavadocTaskName(), Javadoc.class, (task) -> { + task.getOptions().setJFlags( javadocFlags( project ) ); + task.doFirst( new Action() { + @Override + public void execute(Task t) { + project.getLogger().lifecycle( + "Generating javadoc with '{}'", + task.getJavadocTool().get().getMetadata().getInstallationPath() + ); + } + } ); + } ); + } + private static List javadocFlags(Project project) { final String jvmArgs = project.property( "toolchain.javadoc.jvmargs" ).toString(); final String[] splits = jvmArgs.split( " " );
+ // + final String constantFieldFqn = row.selectFirst( ".colFirst a" ).id(); + final String simpleFieldName = constantFieldFqn.substring( constantFieldFqn.lastIndexOf( '.' ) + 1 ); + + // "hibernate.dialect"