Kontroluj sesję hibernate(kiedy zamknąć ją ręcznie)

Jestem nowy w hibernate,po przeczytaniu API hibernate i samouczka wydaje się,że sesja powinna zostać zamknięta, gdy nie jest używana.

Tak:

Session sess=getSession();
Transcration tx=sess.beginTranscration();
//do something using teh session
sess.save(obj);
tx.commit();
sess.close;

Nie mam wątpliwości, gdy używam go w samodzielnej aplikacji. Jednak nie jestem pewien, kiedy używasz w aplikacji internetowej.

Na przykład, mam servlet: TestServlet aby odbierać parametry od klienta, następnie wzywam menedżera, aby odpytywał coś zgodnie z parametrami, tak jak to:

class TestServlet{
  doGet(HttpServletRequset,httpServletResponse){
    String para1=request.getParam...();
    String para2=.....
    new Manager().query(para1,para2);
  }
}

class Manager{
  public String query(String pa1,String pa2){
    Session=....// get the session
    //do query using para1 and 1
    session.close() //Here, I wonder if I should close it.
  }
}

Czy powinienem zamknąć sesja w metodzie zapytań?

Ponieważ ktoś mi powiedział, że sesja w hibernate jest jak połączenie w jdbc. Więc otwieranie i zamykanie go tak często jest właściwym sposobem?

BTW, czy tx.commit() jest wymagany za każdym razem?

Również jaki jest problem z używaniem sesji w servlecie, ponieważ widziałem, że sesja nie jest bezpieczna dla wątku w api.

Author: coding_idiot, 2010-10-28

3 answers

Jestem nowy w hibernate,po przeczytaniu API hibernate i samouczka wydaje się, że sesja powinna być cloesd, gdy nie jest używana.

Powinno być zamknięte, gdy skończysz z (ale może to być zrobione automatycznie dla Ciebie, jak zobaczymy).

Nie mam wątpliwości, gdy używam go w samodzielnej aplikacji. Jednak nie jestem pewien, kiedy używasz w aplikacji internetowej.

Jak wyjaśniono w sekcji 11.1.1. Jednostka pracy dokumentacji, najczęściej spotykanym wzorcem w aplikacji klienckiej/serwerowej dla wielu użytkowników jest session-per-request.

Na przykład, mam servlet: TestServlet, aby odbierać parametry od klienta,następnie wzywam menedżera, aby odpytywał coś zgodnie z parametrami: tak po prostu (...) Czy powinienem zamknąć sesję w metodzie query?

Wszystko zależy od tego, jak uzyskasz sesję.

  • jeśli użyjesz sessionFactory.getCurrentSession(), uzyskasz "bieżącą sesję", która jest związany z cyklem życia transakcji i będzie automatycznie spłukiwany i zamykany po zakończeniu transakcji (commit lub rollback).
  • jeśli zdecydujesz się użyć sessionFactory.openSession(), będziesz musiał samodzielnie zarządzać sesją oraz spłukać i zamknąć ją "ręcznie".

Aby zaimplementować wzorzec session-per-request, preferuj pierwsze podejście (znacznie łatwiejsze i mniej gadatliwe). Skorzystaj z drugiego podejścia, aby wdrożyć długie rozmowy.

Strona wiki sesje i transakcje jest dobrym uzupełnieniem dokumentacji na ten temat.

BTW, czy tx.commit() jest wymagany za każdym razem?

Możesz przeczytać Nietransakcyjny dostęp do danych i tryb Auto-commit , aby wyjaśnić kilka rzeczy, ale mówiąc prościej, Twój kod hibernacji musi zostać wykonany w ramach transakcji i sugerowałbym użycie jawnych granic transakcji(tj. jawnych beginTransaction i commit).

Również to, co jest problem z używaniem sesji w servlecie, ponieważ widziałem, że sesja nie jest Bezpieczna w api.

Tylko nie rób z niej zmiennej instancji Servletu i nie będziesz miał żadnego problemu.

Referencje

 106
Author: Pascal Thivent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-15 15:08:08

Jeśli otrzymujesz sesję Przez sessionFactory.openSession(), musisz zamknąć ją zewnętrznie . Otwarta sesja na niezamierzony okres może spowodować wyciek danych. Plus może dać zaproszenie do zagrożenia bezpieczeństwa aplikacji internetowej.

 0
Author: user6069813,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 12:17:48

Możemy wykorzystać ThreadLocal.

public class MyUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
private static final ThreadLocal<Session> threadLocal;

static {
try {
    Configuration configuration = new Configuration();
    configuration.configure();
    serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
    sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    threadLocal = new ThreadLocal<Session>();

    } catch(Throwable t){
      t.printStackTrace();
      throw new ExceptionInInitializerError(t);
    }
}
public static Session getSession() {
    Session session = threadLocal.get();
    if(session == null){
        session = sessionFactory.openSession();
        threadLocal.set(session);
    }
    return session;
}

public static void closeSession() {
    Session session = threadLocal.get();
    if(session != null){
    session.close();
    threadLocal.set(null);
    }
}

public static void closeSessionFactory() {
    sessionFactory.close();
    StandardServiceRegistryBuilder.destroy(serviceRegistry);
   }
}

Tutaj {[2] } jest inicjalizowane tylko raz za pomocą bloku statycznego. Dlatego, gdy klasa main wywoła getSession(), obecność obiektu Session jest najpierw sprawdzana w obiekcie threadLocal. Dlatego ten program zapewnia bezpieczeństwo wątków. Po każdej operacji closeSession() zamknie sesję i ustawi obiekt threadLocal Na null. Na koniec zadzwoń do closeSessionFactory().

 0
Author: AnirbanDebnath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-04 16:22:45