如何在多线程应用程序中使用Hibernate?

我正在尝试将Hibernate用于多线程应用程序,其中每个线程都检索一个对象并将其插入表中。我的代码如下所示。我每个线程都有本地hibernate会话对象,在每个InsertData中,我都执行beginTransaction和commit。

我面临的问题是很多次我收到“ org.hibernate.TransactionException:不支持嵌套事务”

由于我是hibernate的新手,所以我不知道自己在做的事是否正确?请让我知道在多线程应用中使用hibernate的正确方法是什么,以及如何避免上述异常。

谢谢

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();

}

}

我的hibernate配置文件有c3p0.min_size=10c3p0.max_size=20

回答:

使用每个线程会话对象,只要您不在多个线程之间共享会话对象,就可以了。

您收到的错误与多线程用法或会话管理无关。您session.save()对ID的使用以及明确设置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()因为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为主键),则很可能是实现错误。

以上是 如何在多线程应用程序中使用Hibernate? 的全部内容, 来源链接: utcz.com/qa/413526.html

回到顶部