2011-09-02 44 views
20

我正在编写一个简单的项目,一个用Swing编写的业务应用程序,使用Hibernate作为后端。我来自Spring,这让我轻松地使用休眠和事务。无论如何,我设法让Hibernate工作。昨日,一边写一些代码来删除DB豆,我得到这个:为什么我会得到org.hibernate.HibernateException:没有配置CurrentSessionContext

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 

缺失的代码很简单:

Session sess = HibernateUtil.getSession(); 
    Transaction tx = sess.beginTransaction(); 
    try { 
     tx.begin(); 
     sess.delete(ims); 
    } catch (Exception e) { 
     tx.rollback(); 
     throw e; 
    } 
    tx.commit(); 
    sess.flush(); 

和我HibernateUtil.getSession()是:

public static Session getSession() throws HibernateException { 
     Session sess = null; 
     try { 
      sess = sessionFactory.getCurrentSession(); 
     } catch (org.hibernate.HibernateException he) { 
      sess = sessionFactory.openSession(); 
     } 
     return sess; 
    } 

附加细节:我从来没有在我的代码中关闭一个hibernate会话,只是在应用程序关闭时。这是错的吗?为什么我在删除(只为该bean,其他人工作),并且我没有进行其他操作(插入,查询,更新)?

我看周围,我想修改我getSession方法只是在sessionFactory.getCurrentSessionCall(),但我得到:org.hibernate.HibernateException: No CurrentSessionContext configured!

Hibernat的conf:

<hibernate-configuration> 
    <session-factory > 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost/joptel</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.connection.password">******</property> 
    <property name="hibernate.connection.pool_size">1</property> 
    <property name="show_sql">true</property> 
    <property name="hibernate.hbm2ddl.auto">update</property> 


    ..mappings.. 

    </session-factory> 
</hibernate-configuration> 
+0

你的hibernate配置文件是怎么样的? – Santosh

回答

54

我想求你一件事,你为什么试图使用“OpenSession”方法?

public static Session getSession() throws HibernateException {   
    Session sess = null;  
    try {   
     sess = sessionFactory.getCurrentSession(); 
    } catch (org.hibernate.HibernateException he) { 
     sess = sessionFactory.openSession();  
    }    
    return sess; 
} 

你不必调用openSession(),因为getCurrentSession()方法始终是(如果线程,如果你已经配置它是)返回当前会话。

我知道了...... 你在你的hibernate.cfg.xml文件中指定当前环境

应该是:

<property name="hibernate.current_session_context_class">thread</property> 
10

没有CurrentSessionContext配置

阅读参考指南Contextual Sessions。您需要为此configure some provided or custom strategy。在hibernate.cfg.xml文件中,你会与

<property name="hibernate.current_session_context_class">...</property> 

你可能想使用“线程”的值来获得每个线程的会话配置。在使用Spring时,它会自动将其设置为SpringSessionContext,从而允许Spring轻松地将Hibernate与其事务管理框架集成。

我来自Spring,这给了我简单的方法来使用休眠和事务。

如果您熟悉Spring,为什么不使用它来管理Hibernate?你必须已经知道它是如何简单和万无一失的。

我从来没有在应用程序关闭时关闭我的代码中的hibernate会话。这是错的吗?

是的,这是非常错误的。没有关闭的每个会话都是开放的数据库连接,所以您的应用程序目前正在流失连接。

非法企图的集合有两个打开的会话

这意味着正是它说关联。你试图对已经关联到不同会话的东西进行一些持久化操作(save(),update(),delete())。这就是当你每次随机开启新会话时会发生的情况,这是自从SessionFactory.getCurrentSession()在没有设置“当前会话上下文”时总会失败的情况。一般来说,从来没有只是因为其中一个不在。你需要有明确的开场和闭幕会议策略,并且不要让任何事情在这些“策略”之外打开一个会议。这是资源泄漏和错误的肯定途径,就像你遇到的那样。

3

当我在一个门户网站上使用Spring远程处理与休眠时,我遇到了同样的问题。 仅当被调用的服务方法包含多个使用hibernate会话访问数据库的DAO调用时,才会出现此类问题。

而解决方法是为具有多个DAO调用的那些方法设置@Transaction注释。 (意味着在这种方法下所有的DOA调用都应该在一次交易之下)。

相关问题