Управление сессиями с помощью Java Hibernate - PullRequest
8 голосов
/ 21 февраля 2012

У меня есть платформа на основе Hibernate, построенная из сервлетов без сохранения состояния (один используется для регистрации пользователя, а другой - для запроса базы данных).

Я использую сессии Hibernate следующим образом:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
if ((null == session) || (session.isOpen() == false)) {
  session = HibernateUtil.getSessionFactory().openSession();
}

В настоящее время я не закрываю сеанс в конце сервлета, чтобы избежать вызова openSession() (при возможности пытаюсь использовать открытые сеансы).

Какая лучшая практика? когда я должен закрыть эти сессии?

Можете ли вы привести пример?

Заранее спасибо!

Ответы [ 4 ]

14 голосов
/ 21 февраля 2012

Лучшая практика в большинстве случаев - сеанс за запрос.То есть откройте сеанс в начале обработки запроса и закройте его в конце.Это можно сделать, например, в сервлете Filter.

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

Однако ваш код не использует один сеанс для всего приложения - он использует концепцию «текущего сеанса», которая открываетсеанс и сохраняет его в контексте (например, ThreadLocal).Но если вы не закроете его, он останется там навсегда.Кроме того, это вызовет те же проблемы, что и описанные выше, поскольку потоки повторно используются в веб-приложении, и новый запрос в какой-то момент получит старый незакрытый сеанс.

4 голосов
/ 21 февраля 2012

Всегда лучше открывать новый сеанс для каждого запроса и закрывать сеанс после обработки запроса. Нравится

Session session = HibernateUtil.getSessionFactory().openSession();

вместо

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

Если мы используем метод getCurrentSession (), tansaction.commit () / rollback () закрывает соединение.

1 голос
/ 25 ноября 2016

Лучше всего управлять сеансом гибернации, это открывать новый сеанс для каждого запроса.Все зависит от того, как вы получите сеанс.

  • Если вы используете sessionFactory.getCurrentSession (), вы получите «текущий сеанс», который связан с жизненным циклом транзакции и будет автоматическисбрасывается и закрывается при завершении транзакции (фиксация или откат)
  • , если вы решите использовать sessionFactory.openSession (), вам придется самостоятельно управлять сеансом, а также сбрасывать и закрывать его «вручную».
if (!session.isOpen()) {
        session = session.getSessionFactory().openSession();
        session.beginTransaction();
}
0 голосов
/ 13 апреля 2017

Я лучше рекомендую использовать пружинные рамки.Потому что весной вы можете использовать @Transactional на уровне метода, и сессия будет автоматически создана и закрыта менеджером транзакций (если вы не используете какой-либо открытый сеанс в перехватчике представления), используя AOP, который внутренне обрабатывается платформой.

@Autowired
EntityManager em;

@Transactinal
void save(User user){
   em.persist(user);
}

Вот и все. Весно это весело: D

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