我的应用程序具有提供给Spring Ehcache的单片应用程序。它的工作正常。知道缓存配置在服务方法中,并且懒惰加载是正确的从DB查询的对象。例如:
@Transactional
@Override
@Caching(evict = { @CacheEvict(value = "schoolCache", key = "#school.id")})
public Integer save(School school) {
// Code here
}
很明显,在ehcache中保存了什么是学校的懒惰实例。
@RequestMapping(value = "/load/{Id}", method = RequestMethod.GET)
@ResponseBody
public SchoolViewModel load(@PathVariable Integer Id) {
SchoolViewModel schoolViewModel = ModelMapper.map(schoolService.loadByEntityId(Id), SchoolViewModel.class);
return schoolViewModel;
}
如果SchoolViewModel具有ModelMapper在Controller的数据库中获取DB的对象的属性。因此,我将应用程序和配置ehcache聚集到redis。
问题是什么?一开始,当SchoolService的请求查询时,此服务查询来自DB的查询,并且由于Hibernate的会议已经打开时间从Redis获取学校对象,并且没有Hiberante的会话,ModelMapper想要映射到学校中的对象的属性。例外是这样的:
由:org.hibernate.LazyInitializationException:无法 初始化代理 - 没有会话 org.hibernate.proxy.abstractlazyinitializer.Initialize(AbstractLazyInitializer.Java:165) 在 org.hibernate.proxy.abstractlazyinitializer.getimplementation(AbstractLazyInitializer.java:286) 在 org.hibernate.proxy.pojo.javassist.javassistlazyinitializer.invoke(javassistlazyinitializer.java:185)
那我该怎么办?有帮助我的最好方法是什么?非常感谢
您需要初始化服务方法中进一步需要的所有关联:
schoolService.loadByEntityId(Id), SchoolViewModel.class)
所以,您有多个选项:
- 您可以将
JOIN FETCH
与JPQL查询一起使用。 - 您可以使用
Hibernate.initialize(proxy)
或Hibernate.unproxy(proxy)
。 - 您可以简单地浏览懒惰的关联。
- 您可以使用DTO投影,而您永远不会碰到任何
LazyInitializationException
。