@Scheduled @Transactional lazy init collection错误 - 没有代理

时间:2015-08-24 19:25:22

标签: java hibernate jpa scheduled-tasks transactional

我们使用Spring 4,Hibernate,存储库和JPA开发了大约一年的网站。我们使用OpenEntityManagerInViewFilter在通过端点检索数据时保持会话打开,但最近一直在使用计划的操作,现在遇到了问题。

我们在一个类中有一个带有@Scheduled注释的方法,另一个带有@Transactional注释的类中有另一个方法。调用方法在文件系统上查找数据并将其传递给第二个类/方法。

这是代码的简化版本:

grouby

调用processQueueMessages的方法/类具有@Scheduled注释。我尝试在调用者上添加@Transactional注释,但没有用。

我尝试了一些放置注释的变体,但始终会收到此错误: org.hibernate.LazyInitializationException:懒得初始化角色集合:.domain.Metadata.geoLocations,无法初始化代理 - 没有会话

我无法在元数据域对象的定义中进行热切的提取,因为它使用了许多我们不想加载的地方。

我愿意接受建议。

3 个答案:

答案 0 :(得分:1)

经过多次搜索,答案很简单,就像通常那样。我使用配置类,它需要一个注释 @EnableTransactionManagement

答案在Spring数据文档中 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html

我必须已经读了十几页,但错过了关键声明。

答案 1 :(得分:0)

您可以尝试使用hibernate fetch配置文件。

https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/performance.html#performance-fetching-profiles

基本上,您在模型上默认保持相同的延迟加载,但创建一个急切加载地理位置属性的获取配置文件。然后,当您从计划方法加载元数据时,请激活您的获取配置文件。

答案 2 :(得分:0)

似乎metadata对象在从metadataRepository中检索后已经不在事务会话中,否则抛出惰性异常就没有意义了。检查metadataRepository.findOneById(uuid)是否未在单独的交易中运行,例如将其标记为REQUIRES_NEW

为了防止延迟加载异常,您应该通过调用metadataRepository.findOneById或使用fetch join查询来急切地检索数据,将调用内的数据预加载到metadata.getGeoLocations().isEmpty()