我需要在Sping Boot 3,Hibernate 6环境中取消代理分离的Hibernate对象。方法:
@Autowired
private EntityManager entityManager;
@Transactional
public <T> T loadUnproxied(T object) {
if (!Hibernate.isInitialized(object)) {
Session session = entityManager.unwrap(Session.class);
// Reattach detached entity to a session.
// Here it fails:
session.merge(object);
Hibernate.initialize(object);
}
return object;
}
这总是导致这个例外:
java.lang.IllegalArgumentException: Unable to locate persister:
org.hibernate.collection.spi.PersistentBag
对此建议的解决方案基本上是修复实体扫描,但实体检测很好,Spring管理得很好,持久性在其他方面也很好。看起来我的代码为Hibernate打开了第二条路,绕过了Spring持久化。但是我需要访问Spring会话,它已经完成了扫描。@Transactional
似乎没有帮助。
**我不会做的是在调用loadUnproxied(...)
之前将传入的object
加载为EAGER fetch *。**整个概念是传递延迟加载的对象,并且只按需加载所需的数据。
(我真的非常感谢任何帮助,但我发现其他类似的问题,人们提到他们仍然想使用LAZY加载,被如何禁用LAZY加载的答案淹没了。
1条答案
按热度按时间rjzwgtxy1#
我解决了它,有两个问题和解决方案:
session.merge(object)
。必须是session.update(object)
。update
实际上是我的第一选择,但它已被弃用,Hibernate建议使用merge
。但是merge
不起作用。它不会将object
重新连接到会话。1.在调试Hibernate时,
java.lang.IllegalArgumentException: Unable to locate persister: org.hibernate.collection.spi.PersistentBag
异常变得可以理解。当试图取消代理存储在org.hibernate.collection.spi.PersistentBag
中的列表时,就会发生这种情况。Hibernate没有关于如何在分离后重新初始化该列表的数据。只有实体可以重新初始化/取消代理。我发现的唯一解决取消代理列表的方法是完全重新加载容器实体,并在该事务会话中初始化列表。解决方案: