JPA延迟加载与新事务结合

Ethereal Lv4

问题描述

service层开启事务,dao层开启事务,并为REQUIRES_NEW,在service层先通过get方法从A对象中获取关联对象B,然后通过set方法设置C对象的相应于B对象的属性为对象B,即:

1
2
3
4
5
6
7
8
9
10
11
12
@Transactional
void methodService(){
BType B = A.getB();
CType C = new CType();
C.setB(B);
dao.methodDao(C); // 通过springboot注入方式调用
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
void methodDao(CType C){
TypeRepository.save(C);
}

报错为

1
illegally attempted to associate a proxy with two open Sessions

原因

这是因为在A对象中获取B对象设置为了lazy模式,由于循环问题,不能将其设置为fetch模式。当传入新的事务时,由于lazy设置,这个对象B其实还没从数据库拿,于是在新的事务内,试图通过旧事务的proxy来获取B对象,造成问题。

解决方案

传入时就从数据库拿一遍,即通过id形式拿

1
2
3
4
5
6
7
8
9
10
11
12
@Transactional
void methodService(){
BType B = dao.getBById(A.getB().getId()); // 此时真正从数据库
CType C = new CType();
C.setB(B);
dao.methodDao(C); // 通过springboot注入方式调用
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
void methodDao(CType C){
TypeRepository.save(C);
}

参考

[illegally attempted to associate a proxy with two open Sessions](org.springframework.orm.hibernate3.HibernateSystemException: illegally attempted to associate a prox_illegally attempted to associate a proxy with two -CSDN博客 )

如何解决JPA延迟加载no Session报错 - 简书 (jianshu.com)

  • Title: JPA延迟加载与新事务结合
  • Author: Ethereal
  • Created at: 2023-12-28 21:55:14
  • Updated at: 2023-12-28 22:10:15
  • Link: https://ethereal-o.github.io/2023/12/28/JPA延迟加载与新事务结合/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments
On this page
JPA延迟加载与新事务结合