I have an app running Hibernate 4.2.21 on JBoss AS 7.2
We currently have a few @OneToOne relationships which, due to known limitations of lazy loading, will alway fetch eagerly on the inverse side.
In order to enable Lazy loading for inverse relationships I am trying to enable build-time bytecode instrumentation.
Here's what I've done so far...
1) Activate instrumentation using maven-antrun-plugin
(I tried the hibernate-enhance-maven-plugin and couldn't get it working but thats for another question), I now get the following maven output in the build log:
[INFO] --- maven-antrun-plugin:1.7:run (Instrument domain classes) @ MyApp-entities ---
[INFO] Executing tasks
instrument:
[instrument] starting instrumentation
[INFO] Executed tasks
2) Next I annotated all @OneToOne relationships as follows...
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "client", optional=false)
@LazyToOne(LazyToOneOption.NO_PROXY)
public ClientPrefs getClientPrefs() {
return clientPrefs;
}
public void setClientPrefs(ClientPrefs clientPrefs) {
this.clientPrefs = clientPrefs;
}
3) Then I add implement FieldHandled
to the @Entity classes along with private field and getter and setter:
private FieldHandler fieldHandler;
success...I am now getting following output in the deployment log:
15:54:09,720 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 56) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Session
15:54:09,730 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 57) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Session
15:54:09,969 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 56) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Client
15:54:09,970 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 57) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Client
15:54:09,999 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 56) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Country
15:54:10,003 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 57) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Country
15:54:10,054 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 56) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Pool
15:54:10,054 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 57) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.Pool
15:54:10,569 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 56) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.User
15:54:10,624 INFO [org.hibernate.tuple.entity.EntityMetamodel] (ServerService Thread Pool -- 57) HHH000157: Lazy property fetching available for: uk.co.myapp.entities.User
The relationships now no longer eagerly load...but they don't lazy load either, they just return null silently.
I have tried removing the FieldHandled
interface and FieldHandler
field from the Entity as I was not sure if this was necessary, after this I no longer get the 'HHH000157: Lazy property fetching available for:'
message at startup and it goes back to eagerly loading by default.
Am I missing something here? The hibernate docs are not explicit on how to actually set this up
EDIT: Added the Ant task config as per comments:
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-classes</phase>
<id>Instrument domain classes</id>
<configuration>
<target name="instrument">
<taskdef name="instrument"
classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
<classpath>
<path refid="maven.dependency.classpath" />
<path refid="maven.plugin.classpath" />
</classpath>
</taskdef>
<instrument verbose="true">
<fileset dir="${project.build.outputDirectory}">
<include name="MyApp-entities/co/uk/myapp/entities/*.class" />
</fileset>
</instrument>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.21.Final</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.1-GA</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
As usual it was a configuration issue, it seems that the ant run plugin needs to be pointed to an exact directory that contains the entities rather than one of the parent directories
This worked for me...
<instrument verbose="true">
<fileset dir="${project.build.directory}/classes/uk/co/myapp/entities">
<include name="*.class" />
</fileset>
</instrument>