Почему я получаю 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>
Ответы
Ответ 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 с этим методом должны быть в одной транзакции.)