非法尝试将一个集合与两个打开的会话相关联-Dropwizard与Hibernate
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非法尝试将一个集合与两个打开的会话相关联-Dropwizard与Hibernate相关的知识,希望对你有一定的参考价值。
我在我的dropwizard应用程序中使用Hibernate和JPA来帮助我的对象的CRUD操作。这是抛出异常的方法
@RetryOnFailure(attempts = 5,
types = {org.hibernate.exception.LockTimeoutException.class,
org.hibernate.exception.LockAcquisitionException.class},
delay = DATABASE_RETRY_DELAY_SECONDS, unit = TimeUnit.SECONDS)
public MyObject createOrSave(MyObject myObject) {
Session session = sessionFactory.openSession();
session.beginTransaction();
try {
session.saveOrUpdate(service);
session.getTransaction().commit();
} catch (RuntimeException e) {
session.getTransaction().rollback();
throw e;
} finally {
if (session != null && session.isOpen()) {
session.close();
}
}
return myObject;
}
SO上有很多线程可以解决这个问题,到目前为止我已经尝试过了
- 检查会话是否打开,如果是,使用
session.getCurrentSession()
,这会引发错误“transaction is already active
” - 根本不要使用交易
- 检查数据库中是否存在记录,如果是,请使用
session.merge()
elsesession.save()
- 在我的关系中不要使用qazxsw poi,但这导致了“qazxsw poi”
我是出于想法,有什么想法吗?
看一下这个问题,似乎问题是与MyObject上的Element集合的关系被声明为
CascadeType.ALL
有没有其他方法来声明这样,以便在保存或更新myObject时可以修改它?
所以我将映射更改为
trying to refernece transient object error
这摆脱了这个特定映射的错误,但我仍然得到了
@JsonIgnore
@Column
@ElementCollection(targetClass = Long.class)
Set<Long> someLongIds;
对象上所有其他映射的错误。
这是因为该集合是一个集合?而不是线程安全?
听起来Hibernate中有两个打开的Sessions,而MyObject正在从一个传递到另一个。
最简单的解决方案通常是使用相同的 @JsonIgnore
@Column
@ElementCollection(targetClass = Long.class, fetch = fetchType.Lazy)
Set<Long> someLongIds;
。如果使用JTA事务(或Hibernate中的任何其他形式的Illegal attempt to associate a collection with two open sessions. Collection
),可以通过调用Session
找到它。显然,这在多线程环境中是行不通的。
另一条路线是分离contextual sessions。回到第一个Session(问题中没有显示),当从数据库中检索到sessionFactory.getCurrentSession()
时,它也可以从该会话中分离出来:
myObject
这具有解决myObject
的session.detach(myObject);
的效果,因此可以在会话之外访问,或者在另一个会话中访问它们。
以上是关于非法尝试将一个集合与两个打开的会话相关联-Dropwizard与Hibernate的主要内容,如果未能解决你的问题,请参考以下文章
“org.hibernate.HibernateException:非法尝试将集合与两个打开的会话相关联”即使上下文是 Thread
“非法尝试将非集合映射为 @OneToMany、@ManyToMany 或 @CollectionOfElements”