HHH-15170 - Dedicated chapter for "Build Tool Support"
This commit is contained in:
parent
0df4dc1642
commit
9d3726e39d
|
@ -32,6 +32,7 @@ include::chapters/envers/Envers.adoc[]
|
||||||
include::chapters/beans/Beans.adoc[]
|
include::chapters/beans/Beans.adoc[]
|
||||||
include::chapters/portability/Portability.adoc[]
|
include::chapters/portability/Portability.adoc[]
|
||||||
include::chapters/statistics/Statistics.adoc[]
|
include::chapters/statistics/Statistics.adoc[]
|
||||||
|
include::chapters/tooling/Tooling.adoc[]
|
||||||
|
|
||||||
include::appendices/Configurations.adoc[]
|
include::appendices/Configurations.adoc[]
|
||||||
include::appendices/Annotations.adoc[]
|
include::appendices/Annotations.adoc[]
|
||||||
|
|
|
@ -8,13 +8,11 @@ Hibernate 3.x saw the first attempts at bytecode enhancement support in Hibernat
|
||||||
We consider those initial attempts (up until 5.0) completely as an incubation.
|
We consider those initial attempts (up until 5.0) completely as an incubation.
|
||||||
The support for bytecode enhancement in 5.0 onward is what we are discussing here.
|
The support for bytecode enhancement in 5.0 onward is what we are discussing here.
|
||||||
|
|
||||||
[[BytecodeEnhancement-capabilities]]
|
See <<tooling-enhancement>> for discussion of performing enhancement.
|
||||||
==== Capabilities
|
|
||||||
|
|
||||||
Hibernate supports the enhancement of an application Java domain model for the purpose of adding various persistence-related capabilities directly into the class.
|
|
||||||
|
|
||||||
[[BytecodeEnhancement-lazy-loading]]
|
[[BytecodeEnhancement-lazy-loading]]
|
||||||
===== Lazy attribute loading
|
==== Lazy attribute loading
|
||||||
|
|
||||||
Think of this as partial loading support.
|
Think of this as partial loading support.
|
||||||
Essentially, you can tell Hibernate that only part(s) of an entity should be loaded upon fetching from the database and when the other part(s) should be loaded as well.
|
Essentially, you can tell Hibernate that only part(s) of an entity should be loaded upon fetching from the database and when the other part(s) should be loaded as well.
|
||||||
|
@ -46,7 +44,7 @@ The plan is to relax that requirement later.
|
||||||
====
|
====
|
||||||
|
|
||||||
[[BytecodeEnhancement-dirty-tracking]]
|
[[BytecodeEnhancement-dirty-tracking]]
|
||||||
===== In-line dirty tracking
|
==== In-line dirty tracking
|
||||||
|
|
||||||
Historically Hibernate only supported diff-based dirty calculation for determining which entities in a persistence context have changed.
|
Historically Hibernate only supported diff-based dirty calculation for determining which entities in a persistence context have changed.
|
||||||
This essentially means that Hibernate would keep track of the last known state of an entity in regards to the database (typically the last read or write).
|
This essentially means that Hibernate would keep track of the last known state of an entity in regards to the database (typically the last read or write).
|
||||||
|
@ -59,7 +57,7 @@ In this approach Hibernate will manipulate the bytecode of your classes to add "
|
||||||
During the flush time, Hibernate asks your entity what has changed rather than having to perform the state-diff calculations.
|
During the flush time, Hibernate asks your entity what has changed rather than having to perform the state-diff calculations.
|
||||||
|
|
||||||
[[BytecodeEnhancement-dirty-tracking-bidirectional]]
|
[[BytecodeEnhancement-dirty-tracking-bidirectional]]
|
||||||
===== Bidirectional association management
|
==== Bidirectional association management
|
||||||
|
|
||||||
Hibernate strives to keep your application as close to "normal Java usage" (idiomatic Java) as possible.
|
Hibernate strives to keep your application as close to "normal Java usage" (idiomatic Java) as possible.
|
||||||
Consider a domain model with a normal `Person`/`Book` bidirectional association:
|
Consider a domain model with a normal `Person`/`Book` bidirectional association:
|
||||||
|
@ -96,74 +94,8 @@ include::{sourcedir}/BytecodeEnhancementTest.java[tags=BytecodeEnhancement-dirty
|
||||||
Bytecode-enhanced bi-directional association management makes that first example work by managing the "other side" of a bi-directional association whenever one side is manipulated.
|
Bytecode-enhanced bi-directional association management makes that first example work by managing the "other side" of a bi-directional association whenever one side is manipulated.
|
||||||
|
|
||||||
[[BytecodeEnhancement-dirty-tracking-optimizations]]
|
[[BytecodeEnhancement-dirty-tracking-optimizations]]
|
||||||
===== Internal performance optimizations
|
==== Internal performance optimizations
|
||||||
|
|
||||||
Additionally, we use the enhancement process to add some additional code that allows us to optimized certain performance characteristics of the persistence context.
|
Additionally, we use the enhancement process to add some additional code that allows us to optimize certain performance
|
||||||
These are hard to discuss without diving into a discussion of Hibernate internals.
|
characteristics of the persistence context. These are hard to discuss without diving into a discussion of Hibernate internals.
|
||||||
|
|
||||||
[[BytecodeEnhancement-enhancement]]
|
|
||||||
==== Performing enhancement
|
|
||||||
|
|
||||||
[[BytecodeEnhancement-enhancement-runtime]]
|
|
||||||
===== Runtime enhancement
|
|
||||||
|
|
||||||
Currently, runtime enhancement of the domain model is only supported in managed Jakarta Persistence environments following the Jakarta Persistence-defined SPI for performing class transformations.
|
|
||||||
|
|
||||||
Even then, this support is disabled by default. To enable runtime enhancement, specify one of the following configuration properties:
|
|
||||||
|
|
||||||
`*hibernate.enhancer.enableDirtyTracking*` (e.g. `true` or `false` (default value))::
|
|
||||||
Enable dirty tracking feature in runtime bytecode enhancement.
|
|
||||||
|
|
||||||
`*hibernate.enhancer.enableLazyInitialization*` (e.g. `true` or `false` (default value))::
|
|
||||||
Enable lazy loading feature in runtime bytecode enhancement. This way, even basic types (e.g. `@Basic(fetch = FetchType.LAZY`)) can be fetched lazily.
|
|
||||||
|
|
||||||
`*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.
|
|
||||||
|
|
||||||
[NOTE]
|
|
||||||
====
|
|
||||||
Also, at the moment, only annotated classes support runtime enhancement.
|
|
||||||
====
|
|
||||||
|
|
||||||
[[BytecodeEnhancement-enhancement-gradle]]
|
|
||||||
===== Gradle plugin
|
|
||||||
|
|
||||||
Hibernate provides a Gradle plugin that is capable of providing build-time enhancement of the domain model as they are compiled as part of a Gradle build.
|
|
||||||
To use the plugin, a project would first need to apply it:
|
|
||||||
|
|
||||||
.Apply the Gradle plugin
|
|
||||||
====
|
|
||||||
[source,gradle]
|
|
||||||
----
|
|
||||||
include::extras/gradle-example.gradle[]
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
The configuration that is available is exposed through a registered Gradle DSL extension:
|
|
||||||
|
|
||||||
enableLazyInitialization:: Whether enhancement for lazy attribute loading should be done.
|
|
||||||
enableDirtyTracking:: Whether enhancement for self-dirty tracking should be done.
|
|
||||||
enableAssociationManagement:: Whether enhancement for bi-directional association management should be done.
|
|
||||||
|
|
||||||
The default value for all 3 configuration settings is `false`.
|
|
||||||
|
|
||||||
The `enhance { }` block is required in order for enhancement to occur.
|
|
||||||
Enhancement is disabled by default in preparation for additions capabilities (hbm2ddl, etc) in the plugin.
|
|
||||||
|
|
||||||
[[BytecodeEnhancement-enhancement-maven]]
|
|
||||||
===== Maven plugin
|
|
||||||
|
|
||||||
Hibernate provides a Maven plugin capable of providing build-time enhancement of the domain model as they are compiled as part of a Maven build.
|
|
||||||
See the section on the <<BytecodeEnhancement-enhancement-gradle>> for details on the configuration settings. Again, the default for those 3 is `false`.
|
|
||||||
|
|
||||||
The Maven plugin supports one additional configuration settings: failOnError, which controls what happens in case of error.
|
|
||||||
The default behavior is to fail the build, but it can be set so that only a warning is issued.
|
|
||||||
|
|
||||||
.Apply the Maven plugin
|
|
||||||
====
|
|
||||||
[source,xml]
|
|
||||||
----
|
|
||||||
include::extras/maven-example.pom[]
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
apply plugin: 'org.hibernate.orm'
|
|
||||||
|
|
||||||
ext {
|
|
||||||
hibernateVersion = 'hibernate-version-you-want'
|
|
||||||
}
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
dependencies {
|
|
||||||
classpath "org.hibernate:hibernate-gradle-plugin:$hibernateVersion"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hibernate {
|
|
||||||
enhance {
|
|
||||||
enableLazyInitialization = true
|
|
||||||
enableDirtyTracking = true
|
|
||||||
enableAssociationManagement = true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
[[tooling]]
|
||||||
|
== Build Tool Integration
|
||||||
|
|
||||||
|
Hibernate provides a few build-time services available as plugins for
|
||||||
|
https://gradle.org[Gradle], https://maven.org[Maven] and https://ant.org[Ant].
|
||||||
|
|
||||||
|
These services include -
|
||||||
|
|
||||||
|
* Bytecode enhancement
|
||||||
|
* Schema management
|
||||||
|
* Static Metamodel generation
|
||||||
|
|
||||||
|
|
||||||
|
[[tooling-enhancement]]
|
||||||
|
=== Bytecode Enhancement
|
||||||
|
|
||||||
|
Hibernate performs bytecode enhancement through its `org.hibernate.bytecode.enhance.spi.Enhancer`
|
||||||
|
contract. These build time tools provide a way to incorporate configuration and execution of
|
||||||
|
the enhancer into a build.
|
||||||
|
|
||||||
|
See <<BytecodeEnhancement>> for discussion of the capabilities of an enhanced model.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
At the moment, only annotated classes are supported for enhancement.
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
[[tooling-enhancement-runtime]]
|
||||||
|
==== Runtime Bytecode Enhancement
|
||||||
|
|
||||||
|
Hibernate can also perform run-time bytecode enhancement when used in Jakarta EE compliant
|
||||||
|
containers through `jakarta.persistence.spi.ClassTransformer`. See the documentation of
|
||||||
|
your container for any additional details. Run-time enhancement is controlled through
|
||||||
|
3 true/false settings (all of which default to false):
|
||||||
|
|
||||||
|
`hibernate.enhancer.enableDirtyTracking`:: Whether to enhance the model for dirty-tracking
|
||||||
|
`hibernate.enhancer.enableLazyInitialization`:: Whether to enhance the model for lazy loading at the attribute level. This allows
|
||||||
|
even basic types to be fetched lazily. It also allows definition of fetch groups (`LazyGroup`).
|
||||||
|
`hibernate.enhancer.enableAssociationManagement`:: Whether to automatically synchronize a bidirectional association when only one side is changed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[tooling-schema]]
|
||||||
|
=== Schema Management
|
||||||
|
|
||||||
|
|
||||||
|
[[tooling-modelgen]]
|
||||||
|
=== Static Metamodel Generation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[tooling-gradle]]
|
||||||
|
=== Gradle Plugin
|
||||||
|
|
||||||
|
For integrating with Gradle, Hibernate provides the
|
||||||
|
https://plugins.gradle.org/plugin/org.hibernate.orm[org.hibernate.orm] plugin which
|
||||||
|
supports bytecode enhancement and static metamodel generation but not schema tooling.
|
||||||
|
|
||||||
|
[source,gradle]
|
||||||
|
----
|
||||||
|
include::extras/gradle-example.gradle[]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
[[tooling-maven]]
|
||||||
|
=== Maven Plugin
|
||||||
|
|
||||||
|
Hibernate provides a Maven plugin capable of providing build-time enhancement of the domain
|
||||||
|
model as they are compiled as part of a Maven build. See the section on the
|
||||||
|
<<BytecodeEnhancement-enhancement-gradle>> for details on the configuration settings. Again, the default for those 3 is `false`.
|
||||||
|
|
||||||
|
The Maven plugin supports one additional configuration settings: failOnError, which controls what happens in case of error.
|
||||||
|
The default behavior is to fail the build, but it can be set so that only a warning is issued.
|
||||||
|
|
||||||
|
.Apply the Maven plugin
|
||||||
|
====
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
include::extras/maven-example.pom[]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
[[tooling-ant]]
|
||||||
|
=== Ant Plugin
|
||||||
|
|
||||||
|
todo - https://hibernate.atlassian.net/browse/HHH-15171
|
|
@ -0,0 +1,23 @@
|
||||||
|
plugins {
|
||||||
|
// e.g., let's use the 6.0.0.Final version of the plugin
|
||||||
|
id "org.hibernate.orm" version "6.0.0.Final"
|
||||||
|
}
|
||||||
|
|
||||||
|
hibernate {
|
||||||
|
enhancement {
|
||||||
|
// all default to false
|
||||||
|
lazyInitialization true
|
||||||
|
dirtyTracking true
|
||||||
|
associationManagement true
|
||||||
|
}
|
||||||
|
jpaMetamodel {
|
||||||
|
// defaults to true
|
||||||
|
applyGeneratedAnnotation true
|
||||||
|
// defaults to ['raw', 'deprecation']
|
||||||
|
suppress 'raw'
|
||||||
|
// defaults to `${buildDir}/generated/sources/jpaMetamodel
|
||||||
|
generationOutputDirectory "${buildDir}/generated/sources/modelgen"
|
||||||
|
// defaults to `${buildDir}/classes/java/jpaMetamodel
|
||||||
|
compileOutputDirectory "${buildDir}/classes/java/modelgen"
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ public class JpaMetamodelGenerationSpec {
|
||||||
public static final String DSL_NAME = JPA_METAMODEL;
|
public static final String DSL_NAME = JPA_METAMODEL;
|
||||||
|
|
||||||
private final Property<Boolean> applyGeneratedAnnotation;
|
private final Property<Boolean> applyGeneratedAnnotation;
|
||||||
|
private final Project project;
|
||||||
private final SetProperty<String> suppressions;
|
private final SetProperty<String> suppressions;
|
||||||
private final DirectoryProperty generationOutputDirectory;
|
private final DirectoryProperty generationOutputDirectory;
|
||||||
private final DirectoryProperty compileOutputDirectory;
|
private final DirectoryProperty compileOutputDirectory;
|
||||||
|
@ -38,6 +39,8 @@ public class JpaMetamodelGenerationSpec {
|
||||||
@Inject
|
@Inject
|
||||||
@SuppressWarnings( "UnstableApiUsage" )
|
@SuppressWarnings( "UnstableApiUsage" )
|
||||||
public JpaMetamodelGenerationSpec(HibernateOrmSpec ormDsl, Project project) {
|
public JpaMetamodelGenerationSpec(HibernateOrmSpec ormDsl, Project project) {
|
||||||
|
this.project = project;
|
||||||
|
|
||||||
applyGeneratedAnnotation = project.getObjects().property( Boolean.class );
|
applyGeneratedAnnotation = project.getObjects().property( Boolean.class );
|
||||||
applyGeneratedAnnotation.convention( true );
|
applyGeneratedAnnotation.convention( true );
|
||||||
|
|
||||||
|
@ -78,11 +81,23 @@ public class JpaMetamodelGenerationSpec {
|
||||||
return suppressions;
|
return suppressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void suppress(String warning) {
|
||||||
|
suppressions.add( warning );
|
||||||
|
}
|
||||||
|
|
||||||
public DirectoryProperty getGenerationOutputDirectory() {
|
public DirectoryProperty getGenerationOutputDirectory() {
|
||||||
return generationOutputDirectory;
|
return generationOutputDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void generationOutputDirectory(Object ref) {
|
||||||
|
generationOutputDirectory.set( project.file( ref ) );
|
||||||
|
}
|
||||||
|
|
||||||
public DirectoryProperty getCompileOutputDirectory() {
|
public DirectoryProperty getCompileOutputDirectory() {
|
||||||
return compileOutputDirectory;
|
return compileOutputDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void compileOutputDirectory(Object ref) {
|
||||||
|
compileOutputDirectory.set( project.file( ref ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue