Hibernate openSession() vs getCurrentSession()
У меня есть некоторые вопросы об использовании Hibernate в веб-приложении JSP.
-
Каким должно быть значение для hibernate.current_session_context_class
?
-
Затем, какое из следующих утверждений следует использовать? И почему?
Session s = HibernateUtil.getSessionFactory().openSession();
Session s = HibernateUtil.getSessionFactory().getCurrentSession()
-
Наконец, какой из них лучше "один сеанс для каждого веб-приложения" или "один сеанс за запрос"?
Ответы
Ответ 1
Как объясняется в этом форуме post, 1 и 2 связаны. Если вы установите hibernate.current_session_context_class
на поток, а затем реализуете что-то вроде фильтра сервлета, который открывает сеанс, - тогда вы можете получить доступ к этому сеансу в другом месте, используя SessionFactory.getCurrentSession()
.
SessionFactory.openSession()
всегда открывает новый сеанс, который вы должны закрыть, когда закончите работу. SessionFactory.getCurrentSession()
возвращает сессию, связанную с контекстом, - вам не нужно закрывать это.
Если вы используете Spring или EJB для управления транзакциями, вы можете настроить их для открытия и закрытия сеансов вместе с транзакциями.
Вы никогда не должны использовать one session per web app
- сеанс не является потокобезопасным объектом - не может использоваться несколькими потоками. Вы всегда должны использовать "один сеанс на запрос" или "один сеанс на транзакцию"
Ответ 2
Если мы говорим о SessionFactory.openSession()
- Он всегда создает новый объект Session.
- Вам необходимо явно очистить и закрыть объекты сеанса.
- В однопоточной среде это медленнее, чем getCurrentSession().
- Вам не нужно настраивать какое-либо свойство для вызова этого метода.
И если мы говорим о SessionFactory.getCurrentSession()
- Он создает новый сеанс, если он не существует, иначе использует тот же сеанс, который находится в текущем контексте гибернации.
- Вам не нужно сбрасывать и закрывать объекты сеанса, Hibernate автоматически позаботится об этом.
- В однопоточной среде это быстрее, чем openSession().
- Вам необходимо настроить дополнительное свойство. "hibernate.current_session_context_class" для вызова метода getCurrentSession(), в противном случае он выдаст исключение.
Ответ 3
openSession
: когда вы вызываете SessionFactory.openSession
, он всегда создает новый объект Session
и передает его вам.
Вам необходимо явно очистить и закрыть эти объекты сеанса.
Поскольку объекты сеанса не являются поточно-ориентированными, вам необходимо создать один объект сеанса на запрос в многопоточной среде и один сеанс на запрос в веб-приложениях.
getCurrentSession
: Когда вы вызываете SessionFactory.getCurrentSession
, он предоставит вам объект сеанса, который находится в контексте гибернации и управляется внутренне hibernate. Это связано с объемом транзакции.
Когда вы вызываете SessionFactory.getCurrentSession
, он создает новый Session
если он не существует, в противном случае используйте тот же сеанс, который находится в текущем контексте гибернации. Он автоматически сбрасывает и закрывает сеанс, когда транзакция заканчивается, поэтому вам не нужно делать это извне.
Если вы используете hibernate в однопоточной среде, вы можете использовать getCurrentSession
, так как он быстрее по сравнению с созданием нового сеанса каждый раз.
Вам нужно добавить следующее свойство в hibernate.cfg.xml, чтобы использовать метод getCurrentSession
:
<session-factory>
<!-- Put other elements here -->
<property name="hibernate.current_session_context_class">
thread
</property>
</session-factory>
Ответ 4
SessionFactory: "Один SessionFactory для каждого приложения на базу данных"
(
например.,
если вы используете 3 DataBase в нашем приложении, вам нужно создать объект sessionFactory для каждого БД, полностью вам нужно создать 3 sessionFactorys. или если у вас только одна база данных Одна сессия достаточно
).
Сессия: "Один сеанс для одного цикла запроса-ответа". вы можете открыть сеанс, когда запрос пришел, и вы можете закрыть сеанс после завершения процесса запроса.
Примечание. -Не используйте один сеанс для веб-приложения.