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/portability/Portability.adoc[]
|
||||
include::chapters/statistics/Statistics.adoc[]
|
||||
include::chapters/tooling/Tooling.adoc[]
|
||||
|
||||
include::appendices/Configurations.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.
|
||||
The support for bytecode enhancement in 5.0 onward is what we are discussing here.
|
||||
|
||||
[[BytecodeEnhancement-capabilities]]
|
||||
==== Capabilities
|
||||
See <<tooling-enhancement>> for discussion of performing enhancement.
|
||||
|
||||
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]]
|
||||
===== Lazy attribute loading
|
||||
==== Lazy attribute loading
|
||||
|
||||
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.
|
||||
|
@ -46,7 +44,7 @@ The plan is to relax that requirement later.
|
|||
====
|
||||
|
||||
[[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.
|
||||
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.
|
||||
|
||||
[[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.
|
||||
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.
|
||||
|
||||
[[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.
|
||||
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[]
|
||||
----
|
||||
====
|
||||
Additionally, we use the enhancement process to add some additional code that allows us to optimize certain performance
|
||||
characteristics of the persistence context. These are hard to discuss without diving into a discussion of Hibernate internals.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
private final Property<Boolean> applyGeneratedAnnotation;
|
||||
private final Project project;
|
||||
private final SetProperty<String> suppressions;
|
||||
private final DirectoryProperty generationOutputDirectory;
|
||||
private final DirectoryProperty compileOutputDirectory;
|
||||
|
@ -38,6 +39,8 @@ public class JpaMetamodelGenerationSpec {
|
|||
@Inject
|
||||
@SuppressWarnings( "UnstableApiUsage" )
|
||||
public JpaMetamodelGenerationSpec(HibernateOrmSpec ormDsl, Project project) {
|
||||
this.project = project;
|
||||
|
||||
applyGeneratedAnnotation = project.getObjects().property( Boolean.class );
|
||||
applyGeneratedAnnotation.convention( true );
|
||||
|
||||
|
@ -78,11 +81,23 @@ public class JpaMetamodelGenerationSpec {
|
|||
return suppressions;
|
||||
}
|
||||
|
||||
public void suppress(String warning) {
|
||||
suppressions.add( warning );
|
||||
}
|
||||
|
||||
public DirectoryProperty getGenerationOutputDirectory() {
|
||||
return generationOutputDirectory;
|
||||
}
|
||||
|
||||
public void generationOutputDirectory(Object ref) {
|
||||
generationOutputDirectory.set( project.file( ref ) );
|
||||
}
|
||||
|
||||
public DirectoryProperty getCompileOutputDirectory() {
|
||||
return compileOutputDirectory;
|
||||
}
|
||||
|
||||
public void compileOutputDirectory(Object ref) {
|
||||
compileOutputDirectory.set( project.file( ref ) );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue