Почему я получаю org.hibernate.HibernateException: не настроен CurrentSessionContext - PullRequest
21 голосов
/ 02 сентября 2011

Я пишу простой проект, бизнес-приложение, написанное на Swing, использующее Hibernate для бэк-энда. Я пришел из Spring, который дал мне простые способы использования гибернации и транзакций. В любом случае мне удалось заставить Hibernate работать. Вчера при написании кода для удаления компонента из БД я получил следующее:

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

дополнительные сведения: я никогда не закрываю сеанс гибернации в своем коде, только при закрытии приложения. Это неправильно? Почему я получаю это при удалении (только для этого компонента, другие работают), а у меня нет при других операциях (вставка, запрос, обновление)?

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

Ответы [ 3 ]

53 голосов
/ 03 сентября 2011

Я хотел спросить вас об одном: почему вы пытаетесь использовать метод "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 голосов
/ 03 сентября 2011

Не настроен 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 голосов
/ 04 октября 2012

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...