1

Hibernate(4.1.8.FINAL)、MySQL(InnoDB)を使用していますが、複数のエンティティの保存で問題が発生しています。

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)
    ...

これが私が書いたコードです(Class 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));
}

例外は、1つのエンティティのみが更新される場合にも発生します。getCurrentSession()の代わりにopenSession()も試しましたが、例外は次のとおりです。

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はトランザクションをサポートしていますか(ドキュメントで説明されているように)?および/または私のコードの何が問題になっているのか教えていただけますか?ありがとうございました :-)

4

1 に答える 1

1

宣言型トランザクション(@Transaction)とプログラム型トランザクションの両方を使用しています。

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

同じコードで両方のトランザクションを使用しているため、Hibernateは文句を言います

org.hibernate.TransactionException: nested transactions not supported

Transactionクラスの上部にあるアノテーションを削除するbeginTransactionと、機能するはずです。それ以外の場合は、とを削除してくださいcommit

それが役に立てば幸い。

于 2012-11-10T22:45:58.770 に答える