为什么我得到 org.hibernate.HibernateException: No CurrentSessionContext 配置

2022-09-02 02:22:12

我正在编写一个简单的项目,一个用Swing编写的商业应用程序,使用Hibernate作为后端。我来自Spring,这给了我使用休眠和交易的简单方法。无论如何,我设法让Hibernate工作。昨天,在编写一些代码以从DB中删除Bean时,我得到了这个:

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

其他详细信息:我从不在代码中关闭休眠会话,只是在应用程序关闭时关闭。这是错的吗?为什么我在删除时得到这个(只针对该bean,其他人确实工作),而我没有在其他操作(插入,查询,更新)上得到这个?

我四处阅读,我试图简单地在,中修改我的方法,但我得到了:getSessionsessionFactory.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>

答案 1

我想问你一件事,你为什么要尝试使用“OpenSession”方法?

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

您不必调用 ,因为方法始终返回当前会话(如果已将其配置为 Thread)。<openSession()getCurrentSession()

知道了!。。。您必须在休眠文件中指定当前上下文.cfg.xml

它应该是:

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

答案 2

未配置当前会话上下文

阅读有关上下文会话的参考指南。您需要为此配置一些提供或自定义的策略。在休眠状态下.cfg.xml,您可以将其配置为

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

您可能希望使用“thread”作为获取每线程会话的值。使用Spring时,它会自动将其设置为SpringSessionContext,允许Spring轻松将Hibernate与其事务管理框架集成。

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

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

我从不在代码中关闭休眠会话,只是在应用程序关闭时关闭。这是错的吗?

是的,这是非常错误的。每个未关闭的会话都是一个开放的数据库连接,因此你的应用当前正在泄漏连接。

非法尝试将集合与两个打开的会话相关联

这完全意味着它所说的。您尝试对已关联到其他会话的内容执行一些持久性操作 (save()、update()、delete())。这就是当你随时随地随机打开新会话时会发生什么,这就是正在发生的事情,因为SessionFactory.getCurrentSession()在没有设置“当前会话上下文”时总是会失败。一般来说,永远不要仅仅因为一个会话还没有打开一个会话。您需要为打开和关闭会话制定明确的策略,并且永远不要让任何内容在这些“策略”之外打开会话。这是导致资源泄漏和错误的可靠途径,就像您遇到的错误一样。


推荐