title: Hibernate DAO in Spring Application: the Session object is automatically never closed, why?
body: <p>I am quite new in Spring world and I have develop a simple DAO using Hibernate that execute CRUD operation on a table in the DB.</p>
  
  <p>Reading here: <a href="http://www.tutorialspoint.com/hibernate/hibernate_sessions.htm" rel="nofollow">http://www.tutorialspoint.com/hibernate/hibernate_sessions.htm</a> I can read that:</p>
  
  <blockquote>
    <p>The Session object is lightweight and designed to be instantiated each
    time an interaction is needed with the database. The session objects
    should not be kept open for a long time because they are not usually
    thread safe and they should be created and destroyed them as needed.</p>
  </blockquote>
  
  <p>Reading online I have understand that Spring automatically open and close the Session object connection respectively when a @Transactional method is call and when it is closed and I don't need to handle manually this thing as is do here: <a href="http://www.tutorialspoint.com/hibernate/hibernate_examples.htm" rel="nofollow">http://www.tutorialspoint.com/hibernate/hibernate_examples.htm</a> (opening the Session when I enter in a CRUD method and close it before exit from it)</p>
  
  <p>My DAO seems work well (correctly perform all the defined CRUD operation on the DB) but seems that the Session is never closed. It is automatically opened when I enter in the first CRUD method called but seems that don't close it when exit from it</p>
  
  <p>I have used the following architecture: I have an <strong>interface</strong> named <strong>PersonDAO</strong> in which I declare the CRUD method that I desire use on my table and then I implement this interface using a concrete class named <strong>PersonDAOImpl2</strong> that implements the declared method by Hibernate.</p>
  
  <p>This is my <strong>PersonDAOImpl2</strong> class code:</p>
  
  <pre><code>package org.andrea.myexample.HibernateOnSpring.dao;
  
  import java.util.List;
  
  import org.andrea.myexample.HibernateOnSpring.entity.Person;
  import org.hibernate.Criteria;
  import org.hibernate.SessionFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Repository;
  import org.springframework.transaction.annotation.Transactional;
  
  @Repository
  @Transactional
  public class PersonDAOImpl2 implements PersonDAO {
  
      // Factory per la creazione delle sessioni di Hibernate:
  
      private SessionFactory sessionFactory;
  
          // Metodo Setter per l'iniezione della dipendenza della SessionFactory:
  
          public void setSessionFactory(SessionFactory sessionFactory) {
              this.sessionFactory = sessionFactory;
              System.out.println("Ho iniettato la SessionFactory: " + sessionFactory);
  
          }
  
          public String getConnectionStatus(){
  
              return " Aperta: " + sessionFactory.getCurrentSession().isOpen() + " Connessa: " + sessionFactory.getCurrentSession().isConnected();
          }
  
  
          /** CREATE CRUD Operation:
           * Aggiunge un nuovo record rappresentato nella tabella rappresentato
           * da un oggetto Person
           */
          @Transactional(readOnly = false)
          public Integer addPerson(Person p) {
  
              System.out.println("Inside addPerson()");
              System.out.println("Connessione aperta: " + sessionFactory.getCurrentSession().isOpen());
              System.out.println("E' connesa:" + sessionFactory.getCurrentSession().isConnected());
  
              Integer personID = personID = (Integer) sessionFactory.getCurrentSession().save(p);
  
              return personID;
  
          }
  
          // READ CRUD Operation (legge un singolo record avente uno specifico id):
          @Transactional
          public Person getById(int id) {
  
              Person retrievedPerson = null;
  
              System.out.println("Inside getById()");
  
              System.out.println("Inside addPerson()");
              System.out.println("Connessione aperta: " + sessionFactory.getCurrentSession().isOpen());
              System.out.println("E' connesa:" + sessionFactory.getCurrentSession().isConnected());
  
              retrievedPerson = (Person) sessionFactory.getCurrentSession().get(Person.class, id);
  
              return retrievedPerson;
  
          }
  
          // READ CRUD Operation (recupera la lista di tutti i record nella tabella):
          @SuppressWarnings("unchecked")
          @Transactional
          public List&lt;Person&gt; getPersonsList() {
  
              System.out.println("Inside getPersonsList()");
              List&lt;Person&gt; personList = null;
  
              Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Person.class);
              personList = criteria.list();
  
              return personList;
          }
  
          // DELETE CRUD Operation (elimina un singolo record avente uno specifico id):
          @Transactional
          public void delete(int id) {
              System.out.println("Inside delete()");
  
              Person personToDelete = getById(id);
              sessionFactory.getCurrentSession().delete(personToDelete);
          }
  
          // UPDATE CRUD OPERATION (aggiorna un determinato record rappresentato da un oggetto)
          @Transactional
          public void update(Person personToUpdate) {
  
              System.out.println("Inside update()");
  
              sessionFactory.getCurrentSession().update(personToUpdate);
          }
  
  }
  </code></pre>
  
  <p>As you can see I inject the dependency of the SessionFactory object that I use to create the Session objects for the interaction with the database, all the CRUD method and a method named <strong>getConnectionStatus()</strong> that only return the status of the connection (return if the connection still remain open and connected)</p>
  
  <p>To test my DAO I have implement a <strong>MainApp</strong> class containing the main() method and in which I test all my CRUD operation, this one:</p>
  
  <pre><code>package org.andrea.myexample.HibernateOnSpring;
  
  import java.util.List;
  import java.util.Iterator;
  
  import org.andrea.myexample.HibernateOnSpring.dao.PersonDAO;
  import org.andrea.myexample.HibernateOnSpring.entity.Person;
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;
  
  public class MainApp {
  
      public static void main(String[] args) {
  
          ApplicationContext context = new ClassPathXmlApplicationContext(
                  "Beans.xml");
          System.out.println("Contesto recuperato: " + context);
  
          Person persona1 = new Person();
  
          persona1.setFirstname("Pippo");
          persona1.setLastname("Blabla");
  
          System.out.println("Creato persona1: " + persona1);
  
          PersonDAO dao = (PersonDAO) context.getBean("personDAOImpl2");
  
          System.out.println("Creato dao object: " + dao);
  
          dao.addPerson(persona1);
  
          System.out.println("persona1 salvata nel database");
          System.out.println("persona1 ha id: " + persona1.getPid());
  
          System.out.println("Recupero l'oggetto Person avente id: "
                  + persona1.getPid());
  
          Person personRetrieved = dao.getById(persona1.getPid());
  
          System.out.println("nome: " + personRetrieved.getFirstname());
          System.out.println("cognome: " + personRetrieved.getLastname());
          System.out.println("ID: " + personRetrieved.getPid());
  
  
          System.out.println("Aggiungo altri 2 record nella tabella: ");
  
          Person persona2 = new Person();
          Person persona3 = new Person();
  
          persona2.setFirstname("Mario");
          persona2.setLastname("Rossi");
          persona3.setFirstname("Paolino");
          persona3.setLastname("Paperino");
  
          dao.addPerson(persona2);
          dao.addPerson(persona3);
  
          List&lt;Person&gt; listaPersone = dao.getPersonsList();
  
          for (Iterator iterator = listaPersone.iterator(); iterator.hasNext();) {
              Person persona = (Person) iterator.next();
              System.out.print("Nome: " + persona.getFirstname());
              System.out.print(" Cognome: " + persona.getLastname());
              System.out.println("  ID: " + persona.getPid());
          }
  
  
          System.out.println("Elimina il primo record dalla tabella");
  
          Person firstPerson = listaPersone.get(0);
          System.out.println("Persona da eliminare: " + firstPerson);
  
          dao.delete(firstPerson.getPid());
  
          listaPersone = dao.getPersonsList();
  
          for (Iterator iterator = listaPersone.iterator(); iterator.hasNext();) {
              Person persona = (Person) iterator.next();
              System.out.print("Nome: " + persona.getFirstname());
              System.out.print(" Cognome: " + persona.getLastname());
              System.out.println("  ID: " + persona.getPid());
          }
  
          System.out.println("Aggiorna il primo record della tabella:");
  
          firstPerson = listaPersone.get(0);
  
          System.out.println("Persona da aggiornare: " + firstPerson);
          System.out.print("Nome: " + firstPerson.getFirstname());
          System.out.print(" Cognome: " + firstPerson.getLastname());
          System.out.println("  ID: " + firstPerson.getPid());
  
          System.out.println("CAMBIO DEI DATI:");
  
          firstPerson.setFirstname("Gatto");
          firstPerson.setLastname("Silvestro");
  
          System.out.println("Nuovi dati: " + firstPerson);
          System.out.print("Nome: " + firstPerson.getFirstname());
          System.out.print(" Cognome: " + firstPerson.getLastname());
          System.out.println("  ID: " + firstPerson.getPid());
  
          System.out.println("UPDATING !!!");
  
          dao.update(firstPerson);
  
          listaPersone = dao.getPersonsList();
  
          for (Iterator iterator = listaPersone.iterator(); iterator.hasNext();) {
              Person persona = (Person) iterator.next();
              System.out.print("Nome: " + persona.getFirstname());
              System.out.print(" Cognome: " + persona.getLastname());
              System.out.println("  ID: " + persona.getPid());
          }
  
          System.out.println(dao.getConnectionStatus()); 
  
      }
  
  }
  </code></pre>
  
  <p>This is my XML configuration file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:tx="http://www.springframework.org/schema/tx" 
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd        
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx-3.1.xsd "&gt;
  
      &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"&gt;
          &lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;
          &lt;property name="url" value="jdbc:mysql://localhost:3306/SpringTestDb" /&gt;
          &lt;property name="username" value="root" /&gt;
          &lt;property name="password" value="aprile12" /&gt;
          &lt;property name="initialSize" value="2" /&gt;
          &lt;property name="maxActive" value="5" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="packagesToScan" value="org.andrea.myexample.HibernateOnSpring.entity" /&gt;
          &lt;property name="hibernateProperties"&gt;
              &lt;props&gt;
                  &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/prop&gt;
                  &lt;prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/prop&gt;
                  &lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt;
              &lt;/props&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
      &lt;bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"&gt;
          &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
      &lt;/bean&gt;
  
      &lt;tx:annotation-driven transaction-manager="transactionManager"/&gt;
  
      &lt;bean id="personDAOImpl2" class="org.andrea.myexample.HibernateOnSpring.dao.PersonDAOImpl2" &gt;
          &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
      &lt;/bean&gt;
  
      &lt;!-- Register @Autowired annotation --&gt;
      &lt;bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /&gt;
  &lt;/beans&gt;
  </code></pre>
  
  <p>My DAO seems work well (correctly perform all the definied CRUD operation on the DB) but seemes that the Session is never closed. It is automatically opened when I enter in the first CRUD method called but seems that don't close it when exit from it (I have tested it using a call to <strong>getConnectionStatus()</strong> at the end of main() method) and I am confusing about it...</p>
  
  <p>So I am asking you:</p>
  
  <p>1) Why the Session is not automatically close? is it so bad as I have read in the first Hibernate article have the same Session that still remain open?</p>
  
  <p>2) Using this architecture (the interface and it's implementation) how can automatically close the Session when exit from a CRUD method?</p>
  
  <p>Tnx</p>
  
  <p>Andrea</p>