问题的症结:Repository对象是动态生成的Proxy,我们很难向其中增加代码,所以只能在业务或控制器层增加加载代码,但此时session已经关闭,再查询懒加载对象,就会触发异常,本文就此展开。
本文的写作地:鸭绿江中朝边境2021年8月20日.jpg
1. 加入声明式事务:
在业务方法上增加了@Transaction,这样会将session打开和关闭推迟到业务方法的边界,从而可以完成懒加载的目的,但由于查询方法是没有事务的,所以此方法是不生效的。
2. 使用OpenSessionInView的方式:
在配置文件中加入:
spring:
jpa:
open-in-view: true
此方式将session的打开和关闭放置到了拦截器中,从而可以保证在一次请求过程中,始终处于session的打开,即持久化对象的状态为持久态,从而可以保证在视图得到的对象是可以进行懒加载的。
但此方式要注意:会出现循环引用的问题。
解决方法是:使用jackson的@JsonBackReference;@JsonIgnore;@JsonIgnoreProperties
。
3. 允许在没有事务的状态下,进行对象的懒加载操作。
如前文,查询是没有事务的,所以不能将session的打开和关闭进行推迟到业务的操作,但此配置可以避免此问题(原理仍在探索中),方法如下:
spring:
jpa:
properties:
hibernate:
enable_lazy_load_no_trans: true
同样,在视图层要注意循环引用的问题。