This guide covers Hibernate’s ability to enhance an applications domain model, the ways to perform that enhancement and the capabilities introduced into the domain model by the enhancement.
The capabilities
Hibernate will enhance the classes in an application’s domain model in order to add one or more of the following capabilities:
-
Lazy state initialization
-
Dirtiness tracking
-
Automatic bi-directional association management
-
Performance optimizations
todo : explain each in detail
Performing enhancement
Ultimately all enhancement is handled by the org.hibernate.bytecode.enhance.spi.Enhancer
class. Custom means to
enhancement can certainly be crafted on top of Enhancer, but that is beyond the scope of this guide. Here we
will focus on the means Hibernate already exposes for performing these enhancements.
Run-time enhancement
Currently run-time enhancement of the domain model is only supported in managed JPA environments following the
JPA defined SPI for performing class transformations. Even then, this support is disabled by default. In this
scenario, run-time enhancement can be enabled by specifying hibernate.ejb.use_class_enhancer=true
as a
persistent unit property.
Build-time enhancement
Hibernate also offers the ability to integrate the enhancement of the domain model as part of the normal build cycle of that domain model. Gradle, Ant and Maven are all supported. One possible benefit of this approach is that the enhanced classes are what gets added to the jar and can then be used on both sides of serialization.
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:
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.hibernate:hibernate-gradle-plugin:5.1.0.Final"
}
}
apply plugin: 'org.hibernate.orm'
At the moment there is not much to configure with regard to the Enhancer, but what is configurable is exposed through a DSL extension registered. By default, enhancement will not be done (in preparation for when this Gradle plugin offers additional capabilities). To enable it you must configure the following DSL extension:
hibernate {
enhance {
enableLazyInitialization= true
enableDirtyTracking = true
enableAssociationManagement = true
enableExtendedEnhancement = false
}
}
Currently the "enhance" extension supports 4 properties:
-
enableLazyInitialization
-
enableDirtyTracking
-
enableAssociationManagement
-
enableExtendedEnhancement
Once enhancement overall is enabled, the default for the first 3 properties is true
. Field access is not enhanced by
default, as it can potentially trigger enhancement of code outside the entities, and also because it assumes that all
the target entities are enhanced, which may not always be the case.
Maven Plugin
The Hibernate Maven plugin provides a convenient way to enhance the domain model at build-time when using Maven as the build environment. Much like the Gradle plugin, the current bytecode enhancement capabilities that can be configured on the plugin are:
-
enableLazyInitialization
-
enableDirtyTracking
-
enableAssociationManagement
-
enableExtendedEnhancement
Field access is not enhanced by default, because it can potentially trigger enhancement of code outside the entities. Other capabilities are enabled by default. Even if the plugin is enabled, the bytecode enhancement can be bypassed by disabling all the capabilities.
There is also a parameter failOnError
that controls what happens in case of error. Default behavior is to fail the
build, but it can be set so that only a warning is issued.
To use the Hibernate Maven plugin on a build it must added to the model (pom.xml) along with other plugins that may be already in use. The XML snippet below is an example of how to declare and configure the plugin.
<build>
<plugins>
[...]
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<version>$currentHibernateVersion</version>
<executions>
<execution>
<configuration>
<failOnError>true</failOnError>
<enableLazyInitialization>true</enableLazyInitialization>
<enableDirtyTracking>true</enableDirtyTracking>
<enableAssociationManagement>true</enableAssociationManagement>
<enableExtendedEnhancement>false</enableExtendedEnhancement>
</configuration>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
</plugins>
</build>