LazyInitializationException
LazyInitializationException
参考博客:
the-best-way-to-handle-the-lazyinitializationexception
懒加载的机制:
-
在非刚需查询
LAZY属性时,生成代理类代替真实对象,代理类的属性值均为默认值。 -
在调用
get方法刚需查询时,生成query语句查询真实对象。
由此可知,懒加载的前提条件是必须在session未关闭的情况下进行,否则无法查询真实对象。
解决该异常的思路:
- 保持
session开启 - 一步到位查询所需数据
1.不推荐
参考博客:
The Open Session In View Anti-Pattern
缺点是集成测试速度慢;在无持续事务的情况下,保持session开启,增加连接池压力。
其中提到了N+1问题,参考:
what-is-the-n1-selects-problem-in-orm-object-relational-mapping
如果不是view层查询导致的异常,则开启这个属性也无作用。验证如下:
直接触发@Component下的方法调用testQuery(),与@Controller@Service调用testQuery(),前者未进入OpenSessionInViewFilter.doFilterInternal方法。
hibernate.enable_lazy_load_no_trans Anti-Pattern
在session关闭后,新建连接查询LAZY属性,增大连接池压力。
2.DTO映射查询
除了需要写很多针对性的DTO和查询语句以外,在@ManyToOne@OneToOne的情况下更为适用,在@OneToMany的情况下,通过DTO无法查询包含list的对象。
参考博客:
https://stackoverflow.com/questions/12379238/hql-new-list-within-new-object
3.小结
无完美的解决方案,具体情况具体分析。
另外,注解中FetchType的默认值并非总是LAZY。
如@OneToMany的FetchType默认值是LAZY,而@ManyToOne默认为EAGER。