hibernate用@lazytoone(lazytooneoption.no\u proxy)延迟加载

bfrts1fy  于 2021-07-09  发布在  Java
关注(0)|答案(3)|浏览(531)

我有一个应用程序在jboss上运行Hibernate4.2.21作为7.2
我们目前有一些@onetoone关系,由于已知的延迟加载的限制,它们总是急切地从相反的方面获取。
为了启用反向关系的延迟加载,我尝试启用构建时字节码插装。
这是我到目前为止所做的。。。
1) 使用激活检测 maven-antrun-plugin (我尝试了hibernate enhance maven插件,但无法使其工作,但这是另一个问题),我现在在构建日志中获得以下maven输出:

  1. [INFO] --- maven-antrun-plugin:1.7:run (Instrument domain classes) @ MyApp-entities ---
  2. [INFO] Executing tasks
  3. instrument:
  4. [instrument] starting instrumentation
  5. [INFO] Executed tasks

2) 接下来,我将所有@onetoone关系注解如下。。。

  1. @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "client", optional=false)
  2. @LazyToOne(LazyToOneOption.NO_PROXY)
  3. public ClientPrefs getClientPrefs() {
  4. return clientPrefs;
  5. }
  6. public void setClientPrefs(ClientPrefs clientPrefs) {
  7. this.clientPrefs = clientPrefs;
  8. }

3) 然后我加上 implement FieldHandled 到@entity类以及私有字段、getter和setter:

  1. private FieldHandler fieldHandler;

成功…我现在在部署日志中获得以下输出:

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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任务配置:

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <artifactId>maven-antrun-plugin</artifactId>
  5. <version>1.7</version>
  6. <executions>
  7. <execution>
  8. <phase>process-classes</phase>
  9. <id>Instrument domain classes</id>
  10. <configuration>
  11. <target name="instrument">
  12. <taskdef name="instrument"
  13. classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
  14. <classpath>
  15. <path refid="maven.dependency.classpath" />
  16. <path refid="maven.plugin.classpath" />
  17. </classpath>
  18. </taskdef>
  19. <instrument verbose="true">
  20. <fileset dir="${project.build.outputDirectory}">
  21. <include name="MyApp-entities/co/uk/myapp/entities/*.class" />
  22. </fileset>
  23. </instrument>
  24. </target>
  25. </configuration>
  26. <goals>
  27. <goal>run</goal>
  28. </goals>
  29. </execution>
  30. </executions>
  31. <dependencies>
  32. <dependency>
  33. <groupId>org.hibernate</groupId>
  34. <artifactId>hibernate-core</artifactId>
  35. <version>4.2.21.Final</version>
  36. </dependency>
  37. <dependency>
  38. <groupId>org.javassist</groupId>
  39. <artifactId>javassist</artifactId>
  40. <version>3.18.1-GA</version>
  41. </dependency>
  42. </dependencies>
  43. </plugin>
  44. </plugins>
  45. </build>
mm5n2pyu

mm5n2pyu1#

@LazyToOne(LazyToOneOption.NO_PROXY) 要求 <property name="hibernate.ejb.use_class_enhancer" value="true"/> 在persistence.xml中
lazy,在请求引用时返回加载的真实对象(字节码增强对于此选项是必需的,如果类未增强,则返回代理)除非您负担不起代理的使用,否则应避免此选项
无代理选项

dsekswqp

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)注解。

huwehgph

huwehgph3#

像往常一样,这是一个配置问题,似乎ant-run插件需要指向一个包含实体的确切目录,而不是父目录之一
这对我有用。。。

  1. <instrument verbose="true">
  2. <fileset dir="${project.build.directory}/classes/uk/co/myapp/entities">
  3. <include name="*.class" />
  4. </fileset>
  5. </instrument>

相关问题