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. или если у вас только одна база данных Одна сессия достаточно ).

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