我有一个在JBoss AS 7.2上运行Hibernate 4.2.21的应用程序
我们目前有一些@OneToOne关系,由于known limitations of lazy loading,它们总是急切地在反面获取。
为了启用反向关系的延迟加载,我尝试启用构建时字节码检测。
这是我到目前为止所做的......
1)使用maven-antrun-plugin
激活检测(我尝试了hibernate-enhance-maven-plugin并且无法使其正常工作,但这是另一个问题),我现在在构建中获得以下maven输出日志:
[INFO] --- maven-antrun-plugin:1.7:run (Instrument domain classes) @ MyApp-entities ---
[INFO] Executing tasks
instrument:
[instrument] starting instrumentation
[INFO] Executed tasks
2)接下来,我将所有@OneToOne关系注释如下......
@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)然后我将implement FieldHandled
与私有字段以及getter和setter一起添加到@Entity类中:
private FieldHandler fieldHandler;
成功......我现在在部署日志中获得以下输出:
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
这些关系现在不再急切地加载......但是他们也没有懒惰加载,他们只是默默地返回null。
我尝试从实体中删除FieldHandled
接口和FieldHandler
字段,因为我不确定是否有必要,之后我在启动时不再收到'HHH000157: Lazy property fetching available for:'
消息它会在默认情况下急切地加载。
我在这里遗漏了什么吗? hibernate文档没有明确说明如何实际设置它
编辑:根据评论添加了Ant任务配置:
<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>
答案 0 :(得分:0)
@LazyToOne(LazyToOneOption.NO_PROXY)
在您的persistance.xml中需要<property name="hibernate.ejb.use_class_enhancer" value="true"/>
懒惰,在请求引用时返回加载的实际对象(此选项强制使用字节码增强,如果类没有增强,则返回PROXY )除非您选择此选项无法承担代理人的使用
答案 1 :(得分:0)
像往常一样,这是一个配置问题,似乎需要将ant运行插件指向包含实体而不是父目录之一的确切目录
这对我有用......
{{1}}
答案 2 :(得分:-1)
您应该假冒一对多关系。之所以会这样,是因为延迟加载集合比延迟加载单个可为空的属性要容易得多,但是通常,如果使用复杂的JPQL / HQL查询,此解决方案将非常不便。
另一个是使用构建时间字节码检测。有关更多详细信息,请阅读Hibernate文档:19.1.7。使用懒惰的属性获取。请记住,在这种情况下,必须将@LazyToOne(LazyToOneOption.NO_PROXY)批注添加到一对一关系以使其变得懒惰。仅将抓取设置为LAZY。
最后一种解决方案是使用运行时字节码检测,但是它仅对在成熟的JEE环境中将Hibernate用作JPA提供程序的用户有效(在这种情况下,将“ hibernate.ejb.use_class_enhancer”设置为true应该可以解决问题:实体管理器配置)或使用配置了Spring的Hibernate进行运行时编织(在某些较旧的应用程序服务器上可能很难实现)。在这种情况下,还需要@LazyToOne(LazyToOneOption.NO_PROXY)批注。