我在我的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()
else session.save()
我是出于想法,有什么想法吗?
看一下这个问题,似乎问题是与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);
的效果,因此可以在会话之外访问,或者在另一个会话中访问它们。