JPA/休眠 - 不需要的部分回滚和会话处理
我正在使用无状态EJB类来更新位于数据库中的持久性实体。EJB 中的方法调用完成工作的实现类。我认为导致问题的是,一个名为 的实体与一个实体具有 oneToMany 关系。事情已经完成,会话被更新,其中“级联”到 。发生 时,事务未完全回滚,这会导致错误,原因显而易见。Foo
Bar
Foo
Bar
StaleObjectStateException
EJB:
private Session getSession() throws BusinessException {
if( this.sess == null ) {
ServiceLocator locator = new ServiceLocator();
SessionFactory sf = locator.getHibernateSessionFactory();
this.sess = sf.openSession();
}
return this.sess;
}
private ProductionOrderImpl getImpl() throws BusinessException {
if( this.impl == null ) {
this.impl = new ProductionOrderImpl( getSession() );
}
return this.impl;
}
public void cutoffOrders( ) throws Exception {
Transaction tx = null;
try {
tx = getSession().beginTransaction();
getImpl().cutOffFoos(fooTime);
tx.commit();
} catch (StaleObjectStateException e1){
if (tx != null) tx.rollback();
logger.error( "Failed to cutoff order : " + e1 );
throw new Exception( LocaleMgr.getMessage());
}
finally {
// reset implementation object, close session,
// and reset session object
impl = null;
sess.close();
sess = null;
}
}
实施:
public ProductionOrderImpl(Session sess) {
this.sess = sess;
}
public void cutoffFoos( Timestamp fooTime) throws Exception {
... Code that gets fooList ...
if( fooList != null ) {
for( Foo foo: fooList ) {
for( Bar bar : foo.getBarList() ) {
... Code that does things with existing Barlist ...
if( ... ) {
... Code that makes new Bar object ...
foo.getBarList().add(bar2);
}
}
sess.update( foo );
}
}
}
相关码码:
@OneToMany(cascade=CascadeType.ALL, mappedBy="foo")
@OrderBy("startTime DESC")
Set<Bar> barList;
因此,基本上,当事务尝试回滚时,已更改的 Bar 部分将被回滚,但新的 Bar(代码中的 bar2)记录仍然存在。
任何指导将不胜感激。就像我说的,我相信这里的错误与;可能与 有关,但默认情况下它应该处于关闭状态。sess.update(foo)
autocommit
我相信正在发生的事情是,Session.Update(foo)反过来创建了两个单独的事务。具体来说,更新 (SQL UPDATE),但 保存 (SQL INSERT)。由于事务上下文只会真正看到 SQL UPDATE,因此它完全可以反转。将不得不对此进行更多研究。Foo
Bar
我已尝试将更改为,但它似乎仍无法解决问题。但是,它确实部分解决了问题。它将正确回滚条目,但导致 StaleObjectStateException 的特定条目除外。该特定条目实际上已从数据库中删除...Session.FlushMode
COMMIT