我正在尝试将 Hibernate 用于多线程应用程序,其中每个线程检索一个对象并尝试将其插入表中。我的代码如下所示。
我每个线程都有本地休眠会话对象,并且在每个 InsertData 中我执行 beginTransaction 和提交。
我面临的问题是很多时候我得到“org.hibernate.TransactionException:不支持嵌套事务”
由于我是冬眠新手,我不知道我所做的是否正确?请让我知道在多线程应用程序中使用 hibernate 的正确方法是什么以及如何避免上述异常。
Thanks
public class Worker extends Thread {
private Session session = null;
Worker() {
SessionFactory sf = HibernateUtil.getSessionFactory(); // Singleton
session = sf.openSession();
session.setFlushMode(FlushMode.ALWAYS);
}
public void run() {
// Some loop which will run thousand of times
for (....)
{
InsertData(b);
}
session.close();
}
// BlogPost Table has (pk = id AutoGenerated), dateTime, blogdescription etc.
private void InsertData(BlogPost b) {
session.beginTransaction();
Long id = (Long) session.save(b);
b.setId(id);
session.getTransaction().commit();
}
}
我的休眠配置文件有c3p0.min_size=10
and c3p0.max_size=20
使用每线程会话对象,只要不在多个线程之间共享会话对象,就可以了。
您收到的错误与您的多线程使用或会话管理无关。您的使用情况session.save()
以及明确设置 ID 不太正确。
没有看到您的映射BlogPost
很难说,但是如果你已经告诉 Hibernate 使用id
字段作为主键,并且您正在使用主键的本机生成器,您需要做的就是这样:
session.beginTransaction();
session.persist(b);
session.flush(); // only needed if flush mode is "manual"
session.getTransaction().commit();
Hibernate会帮你填写ID,persist()
将导致插入发生在事务范围内(save()
不关心交易)。如果您的冲水模式未设置为手动,则无需致电flush()
as Transaction.commit()
将为您处理。
请注意,与persist()
,在刷新会话之前,不能保证设置 BlogPost 的 ID,这适合您在此处的使用。
优雅地处理错误:
try {
session.beginTransaction();
try {
session.persist(b);
session.flush(); // only needed if flush mode is "manual"
session.getTransaction().commit();
} catch (Exception x) {
session.getTransaction().rollback();
// log the error
}
} catch (Exception x) {
// log the error
}
顺便说一句,我建议制作BlogPost.setId()
私有的,或包可见的。如果另一个类显式设置 ID(再次假设本机生成器,并且 id 作为主键),则很可能是一个实现错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)