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

got*_*ch4 21 java hibernate

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

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
Run Code Online (Sandbox Code Playgroud)

删除代码很简单:

    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();
Run Code Online (Sandbox Code Playgroud)

而我的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;
    }
Run Code Online (Sandbox Code Playgroud)

其他细节:我从未在我的代码中关闭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>
Run Code Online (Sandbox Code Playgroud)

小智 53

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

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

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

我明白了!...您必须在hibernate.cfg.xml文件中指定当前上下文

它应该是:

<property name="hibernate.current_session_context_class">thread</property>
Run Code Online (Sandbox Code Playgroud)


Rya*_*art 10

没有配置CurrentSessionContext

阅读上下文会话的参考指南.您需要为此配置一些提供的或自定义策略.在hibernate.cfg.xml中,您可以使用它进行配置

<property name="hibernate.current_session_context_class">...</property>
Run Code Online (Sandbox Code Playgroud)

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

我来自Spring,这给了我简单的方法来使用hibernate和事务.

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

我永远不会在我的代码中关闭一个hibernate会话,只是关闭应用程序.这是错的吗?

是的,这是非常错误的.每个未关闭的会话都是一个开放的数据库连接,因此您的应用程序当前正在大量连接.

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

这正是它所说的.您尝试对已经与其他会话关联的内容执行一些持久性操作(save(),update(),delete()).当你随机地随机打开新会话时会发生这种情况,这就是发生的事情,因为当没有设置"当前会话上下文"时,SessionFactory.getCurrentSession()将始终失败.一般情况下,永远不要因为一个人已经在那里而打开一个会话.您需要有明确定义的策略来打开和关闭会话,并且永远不要让任何事情在这些"策略"之外打开会话.这是您遇到的资源泄漏和错误的可靠途径.