JPA中延迟加载异常的解决办法

解决延迟加载的异常(noSession)

1、noSession异常的原因

在使用Jpa时,当表与表之间有关联关系的时候,我们在设计表的关联关系,使用注解设置的时候,如果在注解上添加了一个***fetch = FetchType.LAZY***属性,就是设置为一个懒加载的模式,即什么时候需要使用这个数据,什么时候在在去查询,这个有时候就会出现问题:下面以Employee员工和Dept部门为例
员工与部门是多对一的关系,我们在员工表设置单向多对一关系:

@Entity
@Table(name="employee")
public class Employee extends BaseDomain{
	@Id
    @GeneratedValue
    private Long id; //主键
    private String username;
    private String email;
    @ManyToOne(fetch = FetchType.LAZY) //设置为懒加载的模式
    @JoinColumn(name="department_id")
    private Dept dept;

如上面代码我们在设置关系的时候,使用@ManyToOne添加这个属性就设置为懒加载,后面我在页面上拿数据的时候会报错:
在这里插入图片描述报错信息:500错误,no-Session,即没有会话,因为我们在后台查询到employee的数据以后要在前台显示,在显示部门的时候,我们需要显示部门名称,但是因为懒加载,所以查询employee的时候并没有查询部门的数据,然后前台在展示的需要将部门数据转换为部门名称,此时会发出一条新的请求去查询部门的数据,但是我们在service层操作完以后会将事务关闭,所以这个时候发出请求会报上面的500错误。

2、如何解决

2.1 在web.xml配置文件设置openentityManger过滤器

<!-- 加上OpenEntityManager -->
<filter>
    <filter-name>openEntity</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>openEntity</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

上面设置完以后,运行还是会报错:500错误,没有序列化
这是因为你需要序列化对象有一个属性是一类类型,而你使用了Hibernate的延迟加载所以这里是个Hibernate的代理对象。该代理对象有些属性不能被序列化所以会报错。
在这里插入图片描述

2.2 要解决上面的报错,使用@JsonIgnoreProperties设置一下

在我们关联的字段即设置了@ManyToOne的注解的字段上设置一下上面注解,代码如下:

	@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="department_id")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private Dept dept;

总结:通过上面就可以将解决懒加载出现的问题,其实解决问题的思路:就是把事务提到controller层管理,因为事务一般都是在service层操作完以后就会关闭,我们配置的那个过滤器就是将开启事务管理的过滤器。
但将事务都提到Controller层进行管理,是非常消耗性能的,而且在多对一关系中,我们肯定是要使用到一方数据的,所以完全没有必要设置懒加载,在实际开发中不建议你这样使用

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值