Hibernate openSession () проти getCurrentSession ()


130

У мене є запитання щодо використання Hibernate у веб-додатку JSP.

  1. Якою має бути цінність hibernate.current_session_context_class?

  2. Тоді, яке з наведених тверджень слід використовувати? І чому?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
    
  3. Нарешті, який краще "один сеанс на веб-додаток" чи "один сеанс за запит"?

Відповіді:


145

Як пояснено у цій публікації на форумі , 1 та 2 пов'язані між собою. Якщо ви встановите hibernate.current_session_context_classтему, а потім реалізуєте щось на кшталт фільтра сервлетів, який відкриває сеанс, - ви можете отримати доступ до цього сеансу в будь-якому іншому місці, використовуючи SessionFactory.getCurrentSession().

SessionFactory.openSession()завжди відкриває новий сеанс, який вам доведеться закрити, коли ви закінчите операції. SessionFactory.getCurrentSession()повертає сеанс, прив’язаний до контексту - це не потрібно закривати.

Якщо ви використовуєте Spring або EJB для управління транзакціями, ви можете налаштувати їх на відкриття / закриття сесій разом з транзакціями.

Ніколи не слід використовувати one session per web app- сеанс не є безпечним для потоків об'єктом - не можна ділитися кількома потоками. Ви завжди повинні використовувати "один сеанс на запит" або "один сеанс на транзакцію"


Дякую вам, @gkamal. Я дивлюся на код у Відкритій сесії в документі Переглянути . (Ваше посилання вказує на ці документи.) Автор пропонує використовувати фільтр. У коді фільтра, він не дзвонить openSession()або close(). Він лише дзвонить getCurrentSession(). Я думаю, він налаштований current_session_contextна thread. Тепер я думаю, що розумію getCurrentSession(). Однак я не знаю, коли я повинен використовувати openSession().
wannik

4
Ви будете використовувати OpenSession, якщо не хочете, щоб сеанс був пов'язаний з будь-яким контекстом. Існують деякі ситуації, коли вам знадобиться інший сеанс - крім одного, прив’язаного до контексту (сплячі в сплячому режимі мають обмеження, що ви не можете використовувати оригінальний сеанс) - у цих випадках ви використовуєте OpenSession замість currentSession. OpenSession створює новий сеанс, який потрібно явно закрити. Наприклад, у методі DAO ви будете викликати OpenSession - використовуйте сеанс і закрийте його.
gkamal

я використовую getCurrentSession (); тому що я ініціалізував це у прослуховувачі не фільтрувати це добре з вашого погляду; я використовую mvc2 jsp servlet
shareef

@gkamal - у мене питання, пов’язане з Sessions. Чи можете ви мені допомогти з цим на сайті - stackoverflow.com/questions/23351083/… . Дякую і Ченкі.
Ерран Морад

ІМО, добре дозволити, щоб кожна нитка мала власну сесію, і лише одну сесію, правда?
coderz

31

Якщо ми говоримо про SessionFactory.openSession ()

  • Він завжди створює новий об’єкт сесії.
  • Вам потрібно чітко очистити та закрити об’єкти сеансу.
  • У середовищі з одиночним потоком це повільніше, ніж getCurrentSession ().
  • Для виклику цього методу не потрібно конфігурувати жодне властивість.

А якщо ми говоримо про SessionFactory.getCurrentSession ()

  • Він створює нову сесію, якщо її немає, інакше використовується той же сеанс, який знаходиться в поточному сплячому контексті.
  • Вам не потрібно промивати та закривати об’єкти сеансу, про це автоматично піде догляд в режимі глибокого сну.
  • У середовищі з одиночним потоком це швидше, ніж openSession ().
  • Потрібно налаштувати додаткову властивість. "hibernate.current_session_context_class" викликати метод getCurrentSession (), інакше він викине виняток.

У відповіді вище вказано не використовувати жодного сеансу за веб-сторінку. Таким чином, якби я був використаний getCurrentSession, він повторно використав би те саме сеанс, чи не так?
розбір

9

openSession: Коли ви телефонуєте SessionFactory.openSession, він завжди створює новий Sessionоб'єкт і передає його вам.

Вам потрібно чітко очистити та закрити ці об’єкти сеансу.

Оскільки об'єкти сеансу не є безпечними для потоків, вам потрібно створити один об’єкт сеансу на запит у багатопотоковому середовищі та один сеанс на запит у веб-додатках.

getCurrentSession: Коли ви телефонуєте SessionFactory.getCurrentSession, він надасть вам об’єкт сеансу, який знаходиться в сплячому режимі та керується внутрішньою сплячкою. Він пов'язаний з обсягом транзакцій.

Коли ви телефонуєте SessionFactory.getCurrentSession, він створює новий, Sessionякщо його не існує, інакше використовуйте той самий сеанс, який знаходиться в поточному сплячому контексті. Після закінчення транзакції він автоматично проходить і закриває сеанс, тому не потрібно робити це зовні.

Якщо ви перебуваєте в сплячому режимі в однопотоковому середовищі, ви можете використовувати його getCurrentSession, оскільки він швидше в роботі, порівняно зі створенням нового сеансу кожного разу.

Для використання методу потрібно додати наступне властивість до hibernate.cfg.xmlgetCurrentSession :

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>

Чи сервлет не відкриває нову нитку для кожного запиту? Таким чином, якщо це Java webapp, це вже не однопотокове середовище?
розбір

0
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Parameter            |                                openSession                                 |                                          getCurrentSession                                          |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session  creation    | Always open new session                                                    | It opens a new Session if not exists , else use same session which is in current hibernate context. |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session close        | Need to close the session object once all the database operations are done | No need to close the session. Once the session factory is closed, this session object is closed.    |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Flush and close      | Need to explicity flush and close session objects                          | No need to flush and close sessions , since it is automatically taken by hibernate internally.      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Performance          | In single threaded environment , it is slower than getCurrentSession       | In single threaded environment , it is faster than openSession                                      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Configuration        | No need to configure any property to call this method                      | Need to configure additional property:                                                              |
|                      |                                                                            |  <property name=""hibernate.current_session_context_class"">thread</property>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+

-6

SessionFactory: "Один SessionFactory на додаток на базу даних" (наприклад, якщо ви використовуєте 3 DataBase в нашому додатку, вам потрібно створити об'єкт sessionFactory для кожної БД, цілком потрібно створити 3 sessionFactorys. Або ж, якщо у вас є лише один DataBase One sessionfactory достатньо ).

Сесія: "Один сеанс за один цикл відповіді на запит". Ви можете відкрити сеанс, коли надійшов запит, і Ви можете закрити сеанс після завершення процесу запиту. Примітка: -Не використовуйте один сеанс для веб-додатків.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.