我正面临太多讨论的“”
我正在使用hibernate开发Spring Boot应用程序。
据我所知,如果Entity的属性标记为FetchType.LAZY,则需要具有Hibernate会话才能触发相应的查询以带入相关实体。
以下是一种从父实体检索实体列表的方法:
@Transactional
public List<Portfolio> getSharedPortfolios(String userName){
User user = userService.getUserActive(userName);
List<Portfolio> sharedPortfolios = user.getSharedPortfolios();
//logger.debug("Number of Shared Portfolios: " + sharedPortfolios.size()); <======
return sharedPortfolios;
}
正在从控制器调用 getSharedPortfolios 方法并获取“ org.hibernate.LazyInitializationException”,然后尝试访问此列表(PersistentBag)
使用@Transactional注释进行注释的 getSharedPortfolios 方法,我希望在执行user.getSharedPortfolios()(sharedPortfolios是一个惰性获取列表)时,将初始化各个列表。但是不会发生这种情况。
有人可以向我解释为什么吗?而且,如果我取消注释打印该PersistentBag大小的日志行的注释,为什么不抛出异常?
在这种情况下,我需要使用EntityManager对其进行显式初始化吗?
非常感谢您。
答案 0 :(得分:1)
调用List<Portfolio> sharedPortfolios = user.getSharedPortfolios();
时,分配给sharedPortfolios
的值是一个惰性代理。
如果您仅返回sharedPortfolios
并在@Transactional
方法之外访问它,则会得到LazyInitializationException
另一方面,如果您在sharedPortfolios
方法中访问@Transactional
,则会发生初始化,并返回已初始化的数据。
恕我直言,您描述的是预期的行为。
有多种强制提取的方法:
或者,检查设置
spring.jpa.open-in-view=true
答案 1 :(得分:0)
我不确定这是什么意思
“正在从控制器调用getSharedPortfolios方法”
因此可能不是您的情况,但是如果您从同一类中的另一个方法调用@Transactional
方法,则getSharedPortfolios
注释将不起作用。