HHH-10359 - Have consistent configuration of bytecode enhancement

This commit is contained in:
barreiro 2015-12-05 05:59:15 +00:00 committed by Steve Ebersole
parent d5740b00eb
commit 1590ad145b
11 changed files with 138 additions and 102 deletions

View File

@ -83,7 +83,7 @@ Currently the "enhance" extension supports 4 properties:
* `enableLazyInitialization`
* `enableDirtyTracking`
* `enableAssociationManagement`
* `enableFieldAccessEnhancement`
* `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
@ -102,7 +102,7 @@ on the plugin are:
* `enableLazyInitialization`
* `enableDirtyTracking`
* `enableAssociationManagement`
* `enableFieldAccessEnhancement`
* `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
@ -133,7 +133,7 @@ already in use. The XML snippet below is an example of how to declare and config
<enableLazyInitialization>true</enableLazyInitialization>
<enableDirtyTracking>true</enableDirtyTracking>
<enableAssociationManagement>true</enableAssociationManagement>
<enableFieldAccessEnhancement>false</enableFieldAccessEnhancement>
<enableExtendedEnhancement>false</enableExtendedEnhancement>
</configuration>
<goals>
<goal>enhance</goal>

View File

@ -138,85 +138,106 @@
<section>
<title>Performing enhancement</title>
<para>
There are two methods to perform bytecode enhancement. It can be done during run time or build time,
using one of the provided plugins for build automation tools. Each capability must be enabled
independently, using the respective property:
<variablelist>
<varlistentry>
<term>enableLazyInitialization</term>
<listitem>
<para>
Whether enhancement for lazy attribute loading should be done.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>enableDirtyTracking</term>
<listitem>
<para>
Whether enhancement for self-dirty tracking should be done.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>enableAssociationManagement</term>
<listitem>
<para>
Whether enhancement for bi-directional association management should be done.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Ultimately all enhancement is handled by the <code>org.hibernate.bytecode.enhance.spi.Enhancer</code> 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.
</para>
<section>
<title>Run-time enhancement</title>
<para>
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. To enable run-time enhancement, specify
<property>hibernate.ejb.use_class_enhancer=true</property> as a persistent unit property.
support is disabled by default. To enable run-time enhancement, turn on one or more of the following
properties in the persistent unit:
<example>
<title>Example persistence.xml</title>
<programlisting role="XML"><xi:include href="extras/persistence-example.xml" parse="text"/></programlisting>
</example>
</para>
<para>
Also, at the moment only annotated classes are supported for run-time enhancement
Also, at the moment only annotated classes are supported for run-time enhancement. Only the
classes declared in the persistent unit will be enhanced.
</para>
</section>
<section>
<title>Gradle plugin</title>
<title>Build-time enhancement</title>
<para>
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:
Hibernate provides plugins for Gradle and Maven build tools.
</para>
<example>
<title>Apply the Gradle plugin</title>
<programlisting role="JAVA"><xi:include href="extras/gradle-example.gradle" parse="text"/></programlisting>
</example>
<para>
The configuration that is available is exposed through a registered Gradle DSL extension:
<variablelist>
<varlistentry>
<term>enableLazyInitialization</term>
<listitem>
<para>
Whether enhancement for lazy attribute loading should be done.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>enableDirtyTracking</term>
<listitem>
<para>
Whether enhancement for self-dirty tracking should be done.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>enableAssociationManagement</term>
<listitem>
<para>
Whether enhancement for bi-directional association management should be done.
</para>
</listitem>
</varlistentry>
</variablelist>
The default value for all 3 configuration settings is <literal>true</literal>
</para>
<para>
The <code>enhance { }</code> block is required in order for enhancement to occur; enhancement
is disabled by default in preparation for additions capabilities (hbm2ddl, etc) in the plugin.
</para>
</section>
<section>
<title>Maven plugin</title>
<para>
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 Gradle plugin
for details on the configuration settings. Again, the default for those 3 is <literal>true</literal>.
</para>
<para>
The Maven plugin supports one additional configuration settings: failOnError, which controls
what happens in case of an error. Default behavior is to fail the build, but it can be set so
that only a warning is issued.
</para>
<example>
<title>Apply the Maven plugin</title>
<programlisting role="JAVA"><xi:include href="extras/maven-example.pom" parse="text"/></programlisting>
</example>
</section>
<section>
<title>Gradle plugin</title>
<para>
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.
</para>
<example>
<title>Apply the Gradle plugin</title>
<programlisting role="JAVA"><xi:include href="extras/gradle-example.gradle" parse="text"/></programlisting>
</example>
<para>
The configuration that is available is exposed through a registered Gradle DSL extension. The default
value for all configuration settings is <literal>false</literal>.
</para>
<para>
The <code>enhance { }</code> block is required in order for enhancement to occur. Enhancement
is disabled by default in preparation for additions capabilities (hbm2ddl, etc) in the plugin.
</para>
</section>
<section>
<title>Maven plugin</title>
<para>
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. The configuration has the same properties
as the Gradle plugin and the default value for all settings is also <literal>false</literal>.
</para>
<para>
The Maven plugin supports one additional configuration settings: failOnError, which controls
what happens in case of an error. Default behavior is to fail the build, but it can be set so
that only a warning is issued.
</para>
<example>
<title>Apply the Maven plugin</title>
<programlisting role="XML"><xi:include href="extras/maven-example.pom" parse="text"/></programlisting>
</example>
</section>
</section>
</section>
</chapter>

View File

@ -1,15 +1,17 @@
ext {
hibernateVersion = 'hibernate-version-you-want'
hibernateVersion = 'x.y.z.Final'
}
buildscript {
dependencies {
classpath "org.hibernate:hibernate-gradle-plugin:$hibernateVersion"
}
dependencies {
classpath "org.hibernate:hibernate-gradle-plugin:$hibernateVersion"
}
}
hibernate {
enhance {
// any configuration goes here
}
enhance {
enableLazyInitialization= false
enableDirtyTracking = false
enableAssociationManagement = false
}
}

View File

@ -4,14 +4,14 @@
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<version>$currentHibernateVersion</version>
<version>$hibernateVersion</version>
<executions>
<execution>
<configuration>
<failOnError>true</failOnError>
<enableLazyInitialization>true</enableLazyInitialization>
<enableDirtyTracking>true</enableDirtyTracking>
<enableAssociationManagement>true</enableAssociationManagement>
<enableLazyInitialization>false</enableLazyInitialization>
<enableDirtyTracking>false</enableDirtyTracking>
<enableAssociationManagement>false</enableAssociationManagement>
</configuration>
<goals>
<goal>enhance</goal>

View File

@ -0,0 +1,11 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="Example">
[...]
<properties>
[...]
<property name="hibernate.enhancer.enableLazyInitialization" value="false"/>
<property name="hibernate.enhancer.enableDirtyTracking" value="false"/>
<property name="hibernate.enhancer.enableAssociationManagement" value="false"/>
</properties>
</persistence-unit>
</persistence>

View File

@ -56,22 +56,22 @@ public class MavenEnhancePlugin extends AbstractMojo {
private List<File> sourceSet = new ArrayList<File>();
@Parameter(property = "dir", defaultValue = "${project.build.outputDirectory}")
private String dir = null;
private String dir;
@Parameter(property = "failOnError", defaultValue = "true")
private boolean failOnError = true;
@Parameter(property = "enableLazyInitialization", defaultValue = "true")
private boolean enableLazyInitialization = true;
@Parameter(property = "enableLazyInitialization", defaultValue = "false")
private boolean enableLazyInitialization;
@Parameter(property = "enableDirtyTracking", defaultValue = "true")
private boolean enableDirtyTracking = true;
@Parameter(property = "enableDirtyTracking", defaultValue = "false")
private boolean enableDirtyTracking;
@Parameter(property = "enableAssociationManagement", defaultValue = "true")
private boolean enableAssociationManagement = true;
@Parameter(property = "enableAssociationManagement", defaultValue = "false")
private boolean enableAssociationManagement;
@Parameter(property = "enableExtendedEnhancement", defaultValue = "false")
private boolean enableExtendedEnhancement = false;
private boolean enableExtendedEnhancement;
private boolean shouldApply() {
return enableLazyInitialization || enableDirtyTracking || enableAssociationManagement || enableExtendedEnhancement;
@ -79,7 +79,7 @@ public class MavenEnhancePlugin extends AbstractMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
if ( !shouldApply() ) {
getLog().info( "Skipping Hibernate enhancement plugin execution since there is no feature enabled" );
getLog().warn( "Skipping Hibernate bytecode enhancement plugin execution since no feature is enabled" );
return;
}

View File

@ -67,7 +67,7 @@
<description>Enable enhancement for management of bi-direction associations</description>
</parameter>
<parameter>
<name>enableFieldAccessEnhancement</name>
<name>enableExtendedEnhancement</name>
<type>java.lang.Boolean</type>
<required>false</required>
<editable>true</editable>
@ -77,10 +77,10 @@
<configuration>
<dir>${project.build.outputDirectory}</dir>
<failOnError>true</failOnError>
<enableLazyInitialization>true</enableLazyInitialization>
<enableDirtyTracking>true</enableDirtyTracking>
<enableAssociationManagement>true</enableAssociationManagement>
<enableFieldAccessEnhancement>false</enableFieldAccessEnhancement>
<enableLazyInitialization>false</enableLazyInitialization>
<enableDirtyTracking>false</enableDirtyTracking>
<enableAssociationManagement>false</enableAssociationManagement>
<enableExtendedEnhancement>false</enableExtendedEnhancement>
</configuration>
</mojo>
</mojos>

View File

@ -79,9 +79,10 @@
<configuration>
<dir>${project.build.outputDirectory}</dir>
<failOnError>true</failOnError>
<enableLazyInitialization>true</enableLazyInitialization>
<enableDirtyTracking>true</enableDirtyTracking>
<enableAssociationManagement>true</enableAssociationManagement>
<enableLazyInitialization>false</enableLazyInitialization>
<enableDirtyTracking>false</enableDirtyTracking>
<enableAssociationManagement>false</enableAssociationManagement>
<enableExtendedEnhancement>false</enableExtendedEnhancement>
</configuration>
</mojo>
</mojos>

View File

@ -13,12 +13,12 @@ package org.hibernate.orm.tooling.gradle
* @author Steve Ebersole
*/
class EnhanceExtension {
def boolean enableLazyInitialization = true
def boolean enableDirtyTracking = true
def boolean enableAssociationManagement = true
def boolean enableFieldAccessEnhancement = false
def boolean enableLazyInitialization = false
def boolean enableDirtyTracking = false
def boolean enableAssociationManagement = false
def boolean enableExtendedEnhancement = false
boolean shouldApply() {
return enableLazyInitialization || enableDirtyTracking || enableAssociationManagement || enableFieldAccessEnhancement;
return enableLazyInitialization || enableDirtyTracking || enableAssociationManagement || enableExtendedEnhancement;
}
}

View File

@ -69,6 +69,7 @@ public class HibernatePlugin implements Plugin<Project> {
private void applyEnhancement(final Project project, final HibernateExtension hibernateExtension) {
if ( !hibernateExtension.enhance.shouldApply() ) {
project.getLogger().warn( "Skipping Hibernate bytecode enhancement since no feature is enabled" );
return;
}
@ -112,11 +113,11 @@ public class HibernatePlugin implements Plugin<Project> {
@Override
public boolean doExtendedEnhancement(CtClass classDescriptor) {
return hibernateExtension.enhance.getEnableFieldAccessEnhancement();
return hibernateExtension.enhance.getEnableExtendedEnhancement();
}
};
if ( hibernateExtension.enhance.getEnableFieldAccessEnhancement() ) {
if ( hibernateExtension.enhance.getEnableExtendedEnhancement() ) {
logger.warn( "Extended enhancement is enabled. Classes other than entities may be modified. You should consider access the entities using getter/setter methods and disable this property. Use at your own risk." );
}

View File

@ -35,7 +35,7 @@ class HibernatePluginTest {
enableLazyInitialization = true
enableDirtyTracking = true
enableAssociationManagement = false
enableFieldAccessEnhancement = false
enableExtendedEnhancement = false
}
}
}