Hibernar openSession () vs getCurrentSession ()

130

Tenho algumas perguntas sobre o uso do Hibernate no aplicativo Web JSP.

  1. Qual deve ser o valor hibernate.current_session_context_class?

  2. Então, qual das seguintes afirmações deve ser usada? E porque?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. Por fim, qual é o melhor "uma sessão por aplicativo da web" ou "uma sessão por solicitação"?

wannik
fonte

Respostas:

145

Conforme explicado nesta postagem do fórum , 1 e 2 estão relacionados. Se você configurar o hibernate.current_session_context_classencadeamento e implementar algo como um filtro de servlet que abre a sessão - poderá acessar essa sessão em qualquer outro lugar usando o SessionFactory.getCurrentSession().

SessionFactory.openSession()sempre abre uma nova sessão que você deve fechar quando concluir as operações. SessionFactory.getCurrentSession()retorna uma sessão vinculada a um contexto - você não precisa fechar isso.

Se você estiver usando Spring ou EJBs para gerenciar transações, poderá configurá-los para abrir / fechar sessões junto com as transações.

Você nunca deve usar one session per web app- a sessão não é um objeto seguro para threads - não pode ser compartilhada por vários threads. Você sempre deve usar "uma sessão por solicitação" ou "uma sessão por transação"

Gkamal
fonte
Muito obrigado, @gkamal. Eu olho para o código no documento Open Session in View . (Seu link aponta para esses documentos.) O autor sugere o uso de filtro. Em seu código de filtro, ele não chama openSession()ou close(). Ele só liga getCurrentSession(). Eu acho que ele define current_session_contextpara thread. Agora acho que entendo getCurrentSession(). No entanto, não sei quando devo usar openSession().
Wannik 8/11
4
Você usará o OpenSession se não desejar que a sessão seja vinculada a qualquer contexto. Existem algumas situações em que você precisaria de uma sessão diferente - diferente daquela ligada ao contexto (os Interceptores do Hibernate têm uma limitação de que você não pode usar a sessão original) - nesses casos, você usaria o OpenSession em vez do currentSession. O OpenSession cria uma nova sessão que você deve fechar explicitamente. Por exemplo, em um método DAO, você chamará OpenSession - use a sessão e feche-a.
gkamal
estou usando getCurrentSession (); porque eu o inicializei no ouvinte, não no filtro, isso está ok do seu ponto de vista; estou usando MVC2 jsp servlet
shareef
@ gkamal - Eu tenho uma pergunta relacionada a Sessions. Você pode me ajudar com isso em - stackoverflow.com/questions/23351083/… . Obrigado e chenqui.
precisa saber é o seguinte
Na IMO, é uma boa prática deixar que cada thread realize sua própria sessão, e apenas uma sessão, certo?
Coderz
31

Se falamos sobre SessionFactory.openSession ()

  • Ele sempre cria um novo objeto de sessão.
  • Você precisa liberar e fechar explicitamente os objetos da sessão.
  • No ambiente de thread único, é mais lento que getCurrentSession ().
  • Você não precisa configurar nenhuma propriedade para chamar esse método.

E se falamos sobre SessionFactory.getCurrentSession ()

  • Ele cria uma nova sessão, se não existir, caso contrário, usa a mesma sessão que está no contexto de hibernação atual.
  • Você não precisa liberar e fechar objetos de sessão, eles serão automaticamente tratados internamente pelo Hibernate.
  • No ambiente de thread único, é mais rápido que o openSession ().
  • Você precisa configurar propriedades adicionais. "hibernate.current_session_context_class" para chamar o método getCurrentSession (), caso contrário, ele lançará uma exceção.
Ramu Agrawal
fonte
A resposta acima diz para não usar uma única sessão por webapp. Assim, se eu usasse getCurrentSession, reutilizaria a mesma sessão, não seria?
parsecer 18/12/19
9

openSession: Quando você liga SessionFactory.openSession, ele sempre cria um novo Sessionobjeto e o entrega a você.

Você precisa liberar e fechar explicitamente esses objetos de sessão.

Como os objetos de sessão não são seguros para threads, é necessário criar um objeto de sessão por solicitação no ambiente multithread e uma sessão por solicitação também em aplicativos da web.

getCurrentSession: Quando você ligar SessionFactory.getCurrentSession, ele fornecerá o objeto de sessão que está no contexto de hibernação e gerenciado internamente por hibernação. Está vinculado ao escopo da transação.

Quando você liga SessionFactory.getCurrentSession, ele cria um novo Sessionse não existir; caso contrário, use a mesma sessão que está no contexto de hibernação atual. Ele libera e fecha automaticamente a sessão quando a transação termina, para que você não precise fazer isso externamente.

Se você estiver usando o hibernate no ambiente de thread único, poderá usá- getCurrentSessionlo, pois seu desempenho é mais rápido em comparação à criação de uma nova sessão a cada vez.

Você precisa adicionar a seguinte propriedade ao hibernate.cfg.xml para usar o getCurrentSessionmétodo:

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>
Neeraj Gahlawat
fonte
Um servlet não abre um novo encadeamento para cada solicitação? Portanto, se é um aplicativo da web Java, já não é um ambiente de thread único?
parsecer 18/12/19
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>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
Joby Wilson Mathews
fonte
-6

SessionFactory: "Um SessionFactory por aplicativo por DataBase" (por exemplo, se você usa 3 DataBases em nosso aplicativo, é necessário criar um objeto sessionFactory para cada banco de dados, é necessário criar totalmente 3 sessionFactorys. Ou se você tiver apenas uma sessão do DataBase One basta ).

Sessão: "Uma sessão para um ciclo de solicitação-resposta". você pode abrir a sessão quando a solicitação chegou e pode fechar a sessão após a conclusão do processo de solicitação. Nota: -Não use uma sessão para aplicativo da web.

pantanoso
fonte