Hibernate 4.1.8.FINAL支持事务:是或否?

时间:2012-11-10 22:32:41

标签: java mysql hibernate

我正在使用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));
}

如果只更新一个实体,也会发生异常。我也尝试使用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是否支持事务(如文档中所述)?和/或你能告诉我我的代码有什么问题吗?谢谢: - )

1 个答案:

答案 0 :(得分: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

希望它有所帮助。