yuna@liu 2024-02-26 19:45 采纳率: 0%
浏览 25

外键字段 引起的illegally attempted to associate proxy

外键字段 引起的illegally attempted to associate proxy。
开发语言:java
框架:SSH

A 表有一个外键字段 fd_customer (关联tbl_customer_info表);
B 表也有一个外键字段 fd_customer(关联tbl_customer_info表)。

外层事务中 ,
先查询 的一笔A 表数据,对应的 fd_customer 值为 001。

启动一个新事务,事务传播机制是:PROPAGATION_REQUIRES_NEW
在新事务中:
查询到一笔B 表数据,其对应的 fd_customer 值也为 001。
这个时候如果在这个新事务中再执行 update(b1);

就会抛出异常:
illegally attempted to associate proxy [com.tt.tbl_customer_info#176b6416af7552d18317251498596416] with two open Sessions;

  • 写回答

4条回答 默认 最新

  • 码农阿豪@新空间 优质创作者: Java、后端开发技术领域 2024-02-26 19:46
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如需一对一服务私聊我哦
    问题分析: 这个异常的原因是因为在一个事务中同时使用了两个相同属性的对象,而这两个对象对应的Session不同,导致了proxy的混乱。 具体来说,就是一开始在外层事务中查询了A表数据,并用Session1进行了操作。接下来在新事务中查询了B表数据,同样使用了fd_customer字段,并用Session2进行了操作。当再次使用Session1操作A表数据时,由于此时fd_customer属性被Session2所使用,而Session1并不知道这个属性已经被占用了,就会出现proxy的混乱,进而抛出异常。 解决方案: 1.避免使用相同属性的对象 在以上分析中,异常的出现是因为在两个事务中同时使用了相同属性的对象。因此,解决这个问题最简单的方法就是避免在一个事务中同时使用相同属性的对象。如果要操作相同的属性,在一个事务中完成所有操作即可。 2.使用Session.merge()方法 如果确实需要在一个事务中对两个不同的对象对应的相同属性进行操作,可以使用Session.merge()方法来解决。merge()方法会在Session中查找相同ID的对象,如果没有找到就会创建一个新的对象,然后将值从原对象拷贝到新对象中。这样就可以避免proxy的混乱。 案例: 下面是一个简单的例子,演示如何避免外键字段引起的proxy异常: // 查询A表数据 Session session1 = sessionFactory.openSession(); Transaction tx1 = session1.beginTransaction(); A a = session1.get(A.class, 1L); tx1.commit(); session1.close(); // 在新事务中查询B表数据,并执行操作 Session session2 = sessionFactory.openSession(); Transaction tx2 = session2.beginTransaction(); B b = session2.get(B.class, 1L); b.setFd_customer(a.getFd_customer()); // 使用A对象对应的fd_customer属性 session2.merge(b); // 使用merge()方法避免proxy异常 tx2.commit(); session2.close(); 在以上代码中,先在一个事务中查询了A表数据,并保存为a对象。接下来在新事务中查询了B表数据,并将其中的fd_customer属性设置为a对象对应的fd_customer属性。由于在一个事务中同时操作了两个不同的对象,为了避免proxy异常,我们使用了Session.merge()方法来代替Session.update()方法。最后提交事务并关闭Session。
    评论

报告相同问题?

问题事件

  • 修改了问题 2月26日
  • 创建了问题 2月26日