3

if I use SessionFactory

private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    public Session getSession() {
            return sessionFactory.openSession();
        }

And use it in my DAO class:

public List<Entity> fetchEntities(Date fromDate, Date toDate) {
 Criteria criteria = getSession().createCriteria(Entity.class);
        criteria.add(Restrictions.between("cts", fromDate, toDate));
        criteria.addOrder(Order.desc("cts"));
        return (List<Entity>) criteria.list();
}

Need I close session or not? How curectly do it?

user5620472
  • 2,722
  • 8
  • 44
  • 97
  • 1
    No, this is not the JPA API. Kindly don't tag it as that – Neil Stockton Dec 13 '16 at 10:14
  • in that way , you are managing the session and the transactions by yourself , so yes you have to close it after any CRUD operation , except if you want to reuse the same in the execution chain(*not* in parallel) – AntJavaDev Dec 13 '16 at 11:19

3 Answers3

4
public List<Entity> fetchEntities(Date fromDate, Date toDate) {
 Criteria criteria = getSession().createCriteria(Entity.class);
        criteria.add(Restrictions.between("cts", fromDate, toDate));
        criteria.addOrder(Order.desc("cts"));
        return (List<Entity>) criteria.list();
}

Need I close session or not? How correctly do it?

If you create a session instance and close it for each executed query, it may work but it may also have side effects such as a connection pool bottleneck or a overuse of memory.
close() releases the JDBC connection and performs some cleaning.

The Connection close() method of the org.hibernate.Interface Session class states :

End the session by releasing the JDBC connection and cleaning up.

So you should not open and close the session for each executed query.
You should rather close the connection when all queries associated to a client request/processing (user, batch ...) were executed.
Of course if the client request consists of a single query, it makes sense to close it after the query execution.


Actually you use SessionFactory.openSession() that creates a new session that is not bound to the Hibernate persistence context.
It means that you have to explicitly close the session as you finish working with it otherwise it will never be closed.
Supposing that the method is the single one executed in the client request, you could write something like :

public List<Entity> fetchEntities(Date fromDate, Date toDate) {
     Session session;
     try{
        session = getSession();
        Criteria criteria = session.createCriteria(Entity.class);
        criteria.add(Restrictions.between("cts", fromDate, toDate));
        criteria.addOrder(Order.desc("cts"));
        return (List<Entity>) criteria.list();
       }
       finally {
         if (session != null) {
           session.close();
       }
}

Note that if you used SessionFactory.getCurrentSession(), you would not need to close it explicitly as it obtains the current session from the persistence context that creates the session as the transaction is started and close it as the transaction is finished.

Reginaldo Santos
  • 840
  • 11
  • 24
davidxxx
  • 125,838
  • 23
  • 214
  • 215
0

The scope of the hibernate session should be the current unit of work (i.e. the transaction) (keep it mind that session is not thread safe).

The factory should be kept for the whole app lifecycle.

See also Struggling to understand EntityManager proper use

Community
  • 1
  • 1
Gab
  • 7,869
  • 4
  • 37
  • 68
-1

No. Actually your web franework ( like spring ) or declarative transaction anagement will do this for you. But there are some cases when you would like to manage sessions yourself. Like batch processing - as hibernate session caches are growing constantly

Konstantin Pribluda
  • 12,329
  • 1
  • 30
  • 35
  • The hibernate session (EntityManager in JPA) may be container or application managed, here we are in the 2nd case – Gab Dec 13 '16 at 10:20
  • Hi do you close EntityManager explicitly if you get it out of hibernate session? – Capacytron May 22 '17 at 11:25