我有一个应用程序在jboss上运行Hibernate4.2.21作为7.2
我们目前有一些@onetoone关系,由于已知的延迟加载的限制,它们总是急切地从相反的方面获取。
为了启用反向关系的延迟加载,我尝试启用构建时字节码插装。
这是我到目前为止所做的。。。
1) 使用激活检测 maven-antrun-plugin
(我尝试了hibernate enhance maven插件,但无法使其工作,但这是另一个问题),我现在在构建日志中获得以下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
到@entity类以及私有字段、getter和setter:
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>
3条答案
按热度按时间mm5n2pyu1#
@LazyToOne(LazyToOneOption.NO_PROXY)
要求<property name="hibernate.ejb.use_class_enhancer" value="true"/>
在persistence.xml中lazy,在请求引用时返回加载的真实对象(字节码增强对于此选项是必需的,如果类未增强,则返回代理)除非您负担不起代理的使用,否则应避免此选项
无代理选项
dsekswqp2#
你应该假装一对多的关系。这将起作用,因为集合的延迟加载比单个可空属性的延迟加载容易得多,但是如果使用复杂的jpql/hql查询,通常这种解决方案非常不方便。
另一种是使用构建时字节码插装。有关更多详细信息,请阅读hibernate文档:19.1.7。使用惰性属性获取。请记住,在本例中,您必须向一对一关系添加@lazytoone(lazytooneoption.no\ proxy)注解以使其变懒。将fetch设置为lazy是不够的。
最后一种解决方案是使用运行时字节码插装,但它只适用于那些在成熟的jee环境中使用hibernate作为jpa提供程序的人(在这种情况下,将“hibernate.ejb.use\u class\u enhancer”设置为true应该可以实现技巧:实体管理器配置)或使用hibernate和配置了spring的spring来进行运行时编织(这可能是错误的)在一些较旧的应用服务器上很难实现)。在这种情况下,还需要@lazytoone(lazytooneoption.no\ proxy)注解。
huwehgph3#
像往常一样,这是一个配置问题,似乎ant-run插件需要指向一个包含实体的确切目录,而不是父目录之一
这对我有用。。。