2012-11-10 109 views
1

我正在使用Hibernate(4.1.8.FINAL),MySQL(InnoDB),我遇到了保存多個實體的問題。Hibernate 4.1.8.FINAL支持交易:是或否?

根據Hibernate文檔http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch15.html批處理應予以支持,但我得到以下異常:

org.hibernate.TransactionException: nested transactions not supported 
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:152) 
    at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1395) 
    ... 

這是我寫的代碼(類EntryDaoImpl.java):

@Transaction 
public void saveAll(final Collection<T> entities) { 
    if (CollectionUtils.isEmpty(entities)) { 
     return; 
    } 
    final Session session = this.sessionFactory.getCurrentSession(); 
    Transaction tx = null; 
    try { 
     tx = session.beginTransaction(); 
     for (final T entity : entities) { 
      session.saveOrUpdate(entity); 
     } 
     tx.commit(); 
    } catch (final RuntimeException e) { 
     if (tx != null) { 
      tx.rollback(); 
     } 
     throw e; 
    } finally { 
     session.flush(); 
     session.clear(); 
    } 
} 

而且這裏是JUnit方法:

@Test 
public void deleteAddress() { 
    Entry entry; 
    // Entry 2 has three addresses (delete all those) 
    entry = this.entryDao.findById(2); 
    Assert.assertEquals(3, entry.getAddresses().size()); 
    entry.setAddresses(null); 
    this.entryDao.saveAll(Collections.singleton(entry)); 
} 

exc如果只更新一個實體,也會發生衝突。我也試過用的openSession()代替的getCurrentSession(),但例外是以下幾點:

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 
    at org.hibernate.collection.internal.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:638) 
    at org.hibernate.event.internal.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:65) 

如果我去沒有事務邏輯,那麼它的工作原理。在研究搜索引擎的過程中,我發現許多開發人員告訴Hibernate根本不支持事務。不確定這個陳述是否過時。 困惑

所以我的問題是:Hibernate是否支持事務(如文檔中所述)?和/或者你能告訴我我的代碼有什麼問題嗎?謝謝:-)

+0

@Transaction註釋來自哪裏?你使用spring並且意味着@Transactional?或者另一個聲明式交易系統?如果是,讓它處理事務 - 異常消息表明你試圖在另一個事務中開始一個事務(「嵌套」)。很可能是因爲你從hibernate會話手動打開了一個事務,而聲明式事務系統已經打開了一個事務。 – Pyranja

回答

1

您正在使用聲明性事務(@Transaction)以及編程事務。

tx = session.beginTransaction(); 
for (final T entity : entities) { 
    session.saveOrUpdate(entity); 
} 
tx.commit(); 

由於您使用無論是在相同的代碼交易,Hibernate的抱怨

org.hibernate.TransactionException: nested transactions not supported 

在你班上名列前茅刪除您Transaction註釋,它應該工作,否則刪除您beginTransactioncommit

希望它有幫助。

+0

謝謝你的回覆。我使用事務註釋(不知道爲什麼事務註釋,似乎我在代碼縮小期間刪除了「al」),並且您的提示解決了問題:我無法將Transactional和beginTransaction() – pitschr