Close Opened Hibernation sessions if exist - java

When a Hibernate session is opened (sessionFactory.openSession()) it might be closed. It is ok. In case it is missed to close an opened session which is used to retrieve data (not to save or update or delete) any where in the application, how to close opened sessions if exists?
(Let's say when a JFrame is closed, if there are opened sessions available, they must be closed. Closing sessions can be done by going through the codes one by one, but I mean here, without checking codes, is there any way to close sessions which are missed to close with some piece of code).

Why dont you close the session when your database operation finished?
I mean, In DAO classes you get opened session perform database operation. And in finally block, Close your session.
You can close session like :
finally {
if(session!=null){
session.close();
}
}
OR
You can get the current session using
Session sess = sessionFactory.getCurrentSession();
And close session on closing event of JFrame.
I get following lines from this link
The main contract here is the creation of Session instances. Usually
an application has a single SessionFactory instance and threads
servicing client requests obtain Session instances from this factory.
The internal state of a SessionFactory is immutable. Once it is
created this internal state is set. This internal state includes all
of the metadata about Object/Relational Mapping.
Implementors must be threadsafe.
And it is our duty to close session when finished the operation or transaction. When we close sessionfactory all resources(connection pools etc) are released properly.

Related

Hibernate Contextual sessions

What's the difference between ManagedSessionContext and ThreadLocalSessionContext both has a ThreadLocal in their implementation for maintaining sessions
ThreadLocalSessionContext - It takes care of the hibernate session management activities like :
Creating a session if one doesn't already exist.
Binding the session to the ThreadLocal, so that sessionFactory.getCurrentSession() returns this bound session and unbinds it once the transaction is completed.
Flush and close the session at the end of transaction complete.
ManagedSessionContext - Responsibility of session management activities like above are handled by some external entity (generally some form of interceptor, etc).
In both the cases the session is stored in the ThreadLocal though.
But the call to bind/unbind of the session and especially when to call flush and close on the session are defined via the external entity.
This gives more flexibility, for example, in the case of ThreadLocalSessionContext, the session is closed automatically when the transaction ends and it is not possible to leave the session open for multi-request conversation type of requirements.
In case of ManagedSessionContext, we can implement multi-request conversation (a.k.a session-per-conversation model) the same session needs to be kept open and should be reused across the user requests. So in the first user request we insert/update/delete some entities and in the next request we do some more operations and finally at the end of third interaction we want to commit the data.
Quoting from Managing the current Session section
When a conversation starts, a new Session must be opened and bound with ManagedSessionContext.bind() to serve the first request in the conversation. You also have to set FlushMode.MANUAL on that new Session, because you don’t want any persistence context synchronization to occur behind your back.
All data-access code that now calls sessionFactory.getCurrentSession() receives the Session you bound.
When a request in the conversation completes, you need to call Managed-SessionContext.unbind() and store the now disconnected Session somewhere until the next request in the conversation is made. Or, if this was the last request in the conversation, you need to flush and close the Session.
To represent that pictorially,
Session scoping with ThreadLocalSessionContext
Session scoping implemented for Session-per-conversation using ManagedSessionContext
You can go through the Listing 11.5 of this link for a sample implementation an interceptor that manages the session for session-per-conversation model.

Difference between HibernateTransactionManager and OpenSessionInViewFilter

From the docs - http://docs.spring.io/spring-framework/docs/2.0.x/api/org/springframework/orm/hibernate/HibernateTransactionManager.html
HibernateTransactionManager - Binds a Hibernate Session from the specified factory to the thread, potentially allowing for one thread-bound Session per factory
OpenSessionInViewFilter - This filter makes Hibernate Sessions available via the current thread, which will be autodetected by transaction managers.
What is the difference between both of them and at what scenarios should they be used ?
OpenSessionInViewFilter
Now when you are using OpenSessionInViewFilter, by default the session's flush mode is set to NEVER. So when you try to save something in your action using hibenate and commit it, it wont be reflected in your database. To solve this you need to flush the session in your action class or extend OpenSessionInViewFilter and override closeSession(Session session, SessionFactory sessionFactory).
Now it is also possible that you are maintaining a single transaction for per request. In your action you edit the attributes of a object and update it using session.update(object). But it is not yet commited as some other processing is remaining. At the same time, some other request is invoking a action which tries to retrieve the object which you were updating. Since the object is not yet commited the other request will get the old object. To solve this you need to begin a transaction before you load object and commit the transaction after you update the object. So that as soon as the object is saved/updated it is commited. With this there can be many transaction in single user request but only one session.
The OpenSessionInView pattern only guarantees that the session is open during one single thread execution.
When the page has been rendered and has been returned to the browser, the session gets closed by the filter.
So subsequent requests (e.g. navigation request) require another new session which will be opened by the OpenSessionInViewFilter. But as the "old" person object is not connected to the "new" session, it is considered as disconnected object which's references cannot be loaded lazily.

Session Management with Java Hibernate

I have a Hibernate-based platform, built from stateless servlets (one is used to register a user and the rest to query the db).
I'm using Hibernate's sessions as follows:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
if ((null == session) || (session.isOpen() == false)) {
session = HibernateUtil.getSessionFactory().openSession();
}
Currently I do not close the session at the end of the servlet in order to avoid openSession() call (trying to use opened sessions if possible).
What's the best practice ? when am I supposed to close these sessions ?
Can you please give an example ?
Thanks in advance !
The best practice is in most cases session-per-request. That is, open a session in the beginning of handling a request, and close it in the end. You can do that in a Servlet Filter, for example.
Having one session for the entire application is bad, because it will accumulate a lot of entities in its 1st level cache, which is a memory leak. It may also produce undeterministic results when multiple clients use it at the same time.
Your code, however, is not using one session for the entire application - it is using the "current session" concept, which opens a session and stores it in a context (a ThreadLocal for example). But if you don't close it, it will stay there forever. Plus, it will cause the same problems as described above, because threads are reused in a web application, and a new request will get an old, unclosed session at some point.
Its always better to open a new session for every request, and close the session once the request is processed. Like
Session session = HibernateUtil.getSessionFactory().openSession();
instead of
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
If we use the getCurrentSession() method , tansaction.commit() / rollback() closes the connection.
The best is to manage a hibernate session is to open a new session for every request.
It all depends on how you obtain the session.
if you use sessionFactory.getCurrentSession(), you'll obtain a
"current session" which is bound to the lifecycle of the transaction
and will be automatically flushed and closed when the transaction
ends (commit or rollback)
if you decide to use sessionFactory.openSession(), you'll have to
manage the session yourself and to flush and close it "manually".
if (!session.isOpen()) {
session = session.getSessionFactory().openSession();
session.beginTransaction();
}
I better recommend you to use spring framework. Cause in spring you can use #Transactional at method level and session will be automatically created and closed by transaction manager (unless you are using any open session in view interceptor) using AOP which is internally handled by framework.
#Autowired
EntityManager em;
#Transactinal
void save(User user){
em.persist(user);
}
thats all.spring is fun :D

Open and close Hibernate session

This is how I get a Hibernate Session and create query.
HSession.getSession().createQuery("query here").executeUpdate();
AND
Critaria cr=HSession.getSession().createCritaria(..).. ;
HSession is where my Session factory is located and getSession() method returns a new session
(getSessionFactory().openSession();)
I want to know whether
After calling cr.list(); Is the session is still alive?
If alive, getting this criteria or executing a query way is not good? and
Creating a Session as
Session s=HSession.getSession();
s.createCriteria...
Is the way to use the session and close it using s.close(); ?
Yes, the session will be alive until you close it. You can perform multiple operations against a session, but only close() will close it.
In your case, it looks like the sessions are controlled by whatever HSession is. You'll need to look at that to see if any transactions are performed, how the sessions are managed, etc.
I read about this today ... it said "A Session is opened when getCurrentSession() is called for the first time and closed when the transaction ends."
So according to this: If you have a transaction wrapped around it (and you should have i guess) and call transaction.commit() ... the session is closed.
In your case it should still be open.
Please correct me if I'm wrong with this ... ! :)

When should we close the EntityManagerFactory?

I am pretty new on the ORM's. I just start to read books and documents about Java Persistence API with Hibernate.
I just wondered, closing EntityManagerFactory is similar with jdbc database connection closing?
Should we close it after every persist/update/delete or not? If we don't close it, will the database connection stay opened?
I just wondered, closing EntityManagerFactory is similar with jdbc database connection closing?
This is not exactly true but closing an EntityManagerFactory would be closer to destroying a whole connection pool. If you want to think JDBC connection, you should think EntityManager.
Should we close it after every persist/update/delete or not?
Creating an EntityManagerFactory is a pretty expensive operation and should be done once for the lifetime of the application (you close it at the end of the application). So, no, you should not close it for each persist/update/delete operation.
The EntityManagerFactory is created once for all and you usually get an EntityManager per request, which is closed at the end of the request (EntityManager per request is the most common pattern for a multi-user client/server application).
If we don't close it, will the database connection stay opened?
As hinted, it's the EntityManager that is actually associated to a database connection and closing the EntityManager will actually release the JDBC connection (most often, return it to a pool).

Categories