No Hibernate Session boundNo Hibernate Session bound to thread, and configuration does not allow cr

MultiThreading with Spring and Hibernate(MySQL)

解决方案:
1. 增加注解管理;
@transaction(promoted ,readonly )
这样子既能产生session,不报这个错误又不产生事务;
多线程   multi thread 中遇到,以为是session不安全,多线程问题..最终两次都是发现自己的问题,没有在该加 transaction 注解的地方加 transaction 注解.


How to use Hibernate in a multi threaded application?

脱离spring对hibernate session的管理,自己手动维护管理.

I am trying to use Hibernate for a multi threaded application wherein each thread retrieves an object and tries to insert it into a table. My code looks like below. I have local hibernate Session objects per thread and in each InsertData I do beginTransaction and commit.

The problem I am facing is that many times I get "org.hibernate.TransactionException: nested transactions not supported"

Since I am new to hibernate I don't know if what I am doing is correct or not? Please let me know what is the correct way to use hibernate in multi threaded app and how to avoid the above mentioned exception.

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

My hibernate config file has c3p0.min_size=10 and c3p0.max_size=20

share | edit | flag
 
 
Is that supposed to be b.setId()? –   Lee Meador  Aug 13 '13 at 17:24
 
Yep, just corrected it. Typo happened while trying to create a minimal example of my actual code. –  Rahul  Aug 13 '13 at 17:27
 
add comment
 

1 Answer

up vote 4 down vote accepted

With session-objects-per-thread, as long as you are not sharing session objects between multiple threads, you will be fine.

The error you are receiving is unrelated to your multithreaded usage or your session management. Your usage of session.save() as well as explicitly setting the ID is not quite right.

Without seeing your mapping for BlogPost its hard to tell, but if you have told Hibernate to use the id field as the primary key, and you are using the native generator for primary keys, the all you need to do is this:

session.beginTransaction();
session.persist(b);
session.flush(); // only needed if flush mode is "manual"
session.getTransaction().commit();

Hibernate will fill in the ID for you, persist() will cause the insert to happen within the bounds of the transaction (save() does not care about transactions). If your flush mode is not set to manual then you don't need to call flush() as Transaction.commit() will handle that for you.

Note that with persist(), the BlogPost's ID is not guaranteed to be set until the session is flushed, which is fine for your usage here.

To handle errors gracefully:

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
}

By the way, I suggesting making BlogPost.setId() private, or package visible. It is most likely an implementation error if another class sets the ID explicitly (again assuming native generator, and id as primary key).

share | edit | flag
 
1
 
Thanks Jason, I din't had rollback() due to which a previous exception was leaving a transaction open for the thread and the subsequent beginTransation's used to throw "TransactionException". –   Rahul  Aug 13 '13 at 18:01
 
add comment



### 回答1: org.hibernate.exception: no Hibernate session bound to thread是一个Hibernate框架的异常。在使用Hibernate进行数据库操作时,每个线程在进行数据库操作之前都需要绑定一个Hibernate会话(session),以确保数据库操作的一致性和正确性。这个异常表示当前线程尚未绑定Hibernate会话。 造成这个异常的原因可能有以下几种: 1. 在进行数据库操作之前未正确配置Hibernate的会话管理器。在使用Hibernate之前,我们需要在配置文件中正确配置Hibernate的会话管理器,以确保每个线程都能正确地绑定Hibernate会话。 2. 在数据库操作之前未正确打开Hibernate会话。在进行数据库操作之前,我们需要通过Hibernate的会话管理器打开一个新的Hibernate会话,再进行数据库操作。如果在操作之前未正确打开会话,就会出现这个异常。 3. 在数据库操作之前未正确关闭Hibernate会话。在进行数据库操作之后,我们需要通过Hibernate的会话管理器关闭之前打开的Hibernate会话,以释放资源。如果在操作之后未正确关闭会话,就会出现这个异常。 解决这个异常的方法有以下几种: 1. 检查配置文件中的会话管理器配置是否正确,并确保每个线程在进行数据库操作之前都能正确绑定Hibernate会话。 2. 在进行数据库操作之前,先打开一个新的Hibernate会话,并在操作之后,正确关闭会话。 3. 检查代码中是否有意外的异常导致会话未被正确关闭。可以使用try-catch语句确保在出现异常时也能正确关闭会话。 综上所述,org.hibernate.exception: no Hibernate session bound to thread异常是因为当前线程未绑定Hibernate会话所导致的。通过正确配置会话管理器,并在进行数据库操作前打开会话并在操作后关闭会话,可以解决这个异常。 ### 回答2: org.hibernate.exception: no Hibernate session bound to thread 是一个Hibernate框架的异常。它通常发生在没有将Hibernate Session与当前线程绑定时。 在使用Hibernate框架时,我们通常会在每个请求处理开始时创建一个Hibernate Session,然后在请求处理结束后关闭该Session。这样可以确保每个请求都有一个独立的Session来操作数据库。 当我们在查询、更新或删除数据库记录时,需要通过Hibernate Session来执行这些操作。但是,当没有将Session与当前线程绑定时,就会抛出"no Hibernate session bound to thread"异常。 解决这个异常的方法是在每个请求处理开始时,通过开启一个事务,将Hibernate Session与当前线程绑定起来。可以使用以下代码实现Session与线程的绑定: try { Session session = sessionFactory.openSession(); // 创建Session Transaction tx = session.beginTransaction(); // 开启事务 // 执行数据库操作 session.saveOrUpdate(entity); tx.commit(); // 提交事务 session.close(); // 关闭Session } catch (Exception e) { if (tx != null) { tx.rollback(); // 回滚事务 } e.printStackTrace(); } 上述代码中的sessionFactory是HibernateSessionFactory对象,通过它来创建Session。在开启事务后,执行完数据库操作后,需要提交事务并关闭Session。 这样,就可以确保在每个请求处理期间都有一个Hibernate Session与当前线程绑定,从而避免"no Hibernate session bound to thread"异常的发生。 ### 回答3: 这个错误意味着在使用Hibernate时没有将Hibernate session绑定到当前线程上。Hibernate是一个用于持久化数据的框架,它维护了一个会话(session)来管理与数据库的交互。当在应用程序中使用Hibernate进行数据库操作时,需要确保在每个线程中都有一个Hibernate session与之关联。 出现这个错误的原因可能有以下几种情况: 1. 没有正确地配置Hibernatesession管理方式: 需要在应用程序的配置文件中设置合适的session管理方式,例如使用ThreadLocalSessionContext。 2. 在使用Hibernate进行数据库操作之前,没有手动地将session与当前线程绑定: 需要在每个线程开始进行数据库操作之前,手动地将session与当前线程绑定。 3. 在进行数据库操作之前,已经将session与当前线程解绑: 需要确保在数据库操作完成之前,不要解除session与当前线程的绑定。 解决这个问题的方法有以下几种: 1. 使用合适的session管理方式: 确认在应用程序的配置文件中设置了合适的session管理方式,例如使用ThreadLocalSessionContext。 2. 在每个线程开始进行数据库操作之前,手动地将session与当前线程绑定: 可以使用Hibernate的getCurrentSession()方法来获取一个session,并将其与当前线程绑定。 3. 确保在数据库操作完成之前,不要解除session与当前线程的绑定: 在进行数据库操作的过程中,尽量避免手动解除session与当前线程的绑定。 总而言之,当出现"org.hibernateexception : no hibernate session bound to thread"错误时,需要检查Hibernatesession管理方式是否正确,以及在每个线程开始进行数据库操作时是否正确地将session与当前线程绑定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值