Подтвердить что ты не робот

Почему я получаю org.hibernate.HibernateException: No CurrentSessionContext настроен

Я пишу простой проект, бизнес-приложение, написанное в Swing, используя Hibernate для back-end. Я пришел из Spring, что дало мне простые способы использования спящего режима и транзакций. Во всяком случае, мне удалось работать в Hibernate. Вчера, написав код для удаления 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, другие работают), и я не выполняю другие операции (вставка, запрос, обновление)?

Я читал, и я попытался изменить свой метод 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>
4b9b3361

Ответ 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;
} 

Вам не нужно вызывать openSession(), потому что метод getCurrentSession() всегда возвращает текущий сеанс (Thread в случае, если вы его настроили).

Я понял! Вы должны указать текущий контекст в файле hibernate.cfg.xml

это должно быть:

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

Ответ 2

Нет настройки CurrentSessionContext

Прочтите справочное руководство по Контекстуальные сеансы. Для этого вам необходимо настроить некоторые предоставленные или настраиваемые стратегии. В файле hibernate.cfg.xml вы должны настроить его с помощью

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

Вероятно, вы захотите использовать "поток" в качестве значения для получения сеансов в потоке. При использовании Spring он автоматически устанавливает это на SpringSessionContext, позволяя Spring легко интегрировать Hibernate с его инфраструктурой управления транзакциями.

Я пришел из Spring, что дало мне простые способы использования спящего режима и транзакций.

Если вы знакомы с Spring, почему вы не используете его для управления Hibernate здесь? Вы уже должны знать, насколько прост и надежный он делает это.

Я никогда не закрываю сеанс спящего режима в своем коде, только при закрытии приложения. Это неправильно?

Да, это очень неправильно. Каждый сеанс, который не закрыт, - это открытое соединение с базой данных, поэтому ваше приложение в настоящее время поддерживает геморрагические соединения.

Нелегальная попытка связать коллекцию с двумя открытыми сеансами

Это означает, что именно это говорит. Вы попытались выполнить некоторую операцию сохранения (save(), update(), delete()) над тем, что уже было связано с другим сеансом. Это произойдет, когда вы произвольно открываете новые сессии, когда это происходит, поскольку SessionFactory.getCurrentSession() всегда терпит неудачу, если не установлен "контекст текущего сеанса". В общем, никогда не открывайте сессию только потому, что ее еще нет. Вам нужно иметь четко определенные стратегии для открытия и закрытия сеансов и никогда не позволять чему-либо открывать сеанс за пределами этих "стратегий". Это верный путь к утечкам ресурсов и ошибкам, подобным тем, с которыми вы столкнулись.

Ответ 3

У меня возникла такая же проблема, когда я работаю на портале, где я использую spring удаленный доступ к спящему. Такая проблема возникает только в том случае, если метод вызываемой службы содержит несколько вызовов DAO, которые попадают в базу данных с сеансом спящего режима.

И решение задает аннотацию @Transaction для тех методов с несколькими вызовами DAO. (Подразумевает, что все вызовы DOA с этим методом должны быть в одной транзакции.)