title: org.hibernate.LazyInitializationException: How to properly use Hibernate's lazy loading feature
body: <p>I got some trouble loading a list of objects from my database using Hibernate and lazy=true mode.
  Hope that someone can help me out here.</p>
  
  <p>I have a simple class here called UserAccount which looks like this:</p>
  
  <pre><code>public class UserAccount {
      long id;
      String username;
      List&lt;MailAccount&gt; mailAccounts = new Vector&lt;MailAccount&gt;();
  
      public UserAccount(){
          super();
      }
  
      public long getId(){
          return id;
      }
  
      public void setId(long id){
          this.id = id;
      }
  
      public String getUsername(){
          return username;
      }
  
      public void setUsername(String username){
          this.username = username;
      }
  
      public List&lt;MailAccount&gt; getMailAccounts() {
          if (mailAccounts == null) {
              mailAccounts = new Vector&lt;MailAccount&gt;();
          }
          return mailAccounts;
      }
  
      public void setMailAccounts(List&lt;MailAccount&gt; mailAccounts) {
          this.mailAccounts = mailAccounts;
      }
  }
  </code></pre>
  
  <p>I am mapping this class in Hibernate via the following mapping file:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&gt;
  &lt;hibernate-mapping&gt;
      &lt;class name="test.account.UserAccount" table="USERACCOUNT"&gt;
  
          &lt;id name="id" type="long" access="field"&gt;
              &lt;column name="USER_ACCOUNT_ID" /&gt;
              &lt;generator class="native" /&gt;
          &lt;/id&gt;
  
          &lt;property name="username" /&gt;
  
          &lt;bag name="mailAccounts" table="MAILACCOUNTS" lazy="true" inverse="true" cascade="all"&gt;
              &lt;key column="USER_ACCOUNT_ID"&gt;&lt;/key&gt;
              &lt;one-to-many class="test.account.MailAccount" /&gt;
          &lt;/bag&gt;
  
      &lt;/class&gt;
  &lt;/hibernate-mapping&gt;
  </code></pre>
  
  <p>As you can see, lazy is set to "true" in the bag mapping element.</p>
  
  <p>Saving the data to the database works fine:</p>
  
  <p>Loading also works by calling <code>loadUserAccount(String username)</code> (see code below):</p>
  
  <pre><code>public class HibernateController implements DatabaseController {
      private Session                 session         = null;
      private final SessionFactory    sessionFactory  = buildSessionFactory();
  
      public HibernateController() {
          super();
      }
  
      private SessionFactory buildSessionFactory() {
          try {
              return new Configuration().configure().buildSessionFactory();
          } catch (Throwable ex) {
              System.err.println("Initial SessionFactory creation failed." + ex);
              throw new ExceptionInInitializerError(ex);
          }
      }
  
      public UserAccount loadUserAccount(String username) throws FailedDatabaseOperationException {
          UserAccount account = null;
          Session session = null;
          Transaction transaction = null;
          try {
              session = getSession();
              transaction = session.beginTransaction();
              Query query = session.createQuery("FROM UserAccount WHERE username = :uname").setParameter("uname", username));
              account = (UserAccount) query.uniqueResult();
              transaction.commit();
          } catch (Exception e) {
              transaction.rollback();
              throw new FailedDatabaseOperationException(e);
          } finally {
              if (session.isOpen()) {
                  // session.close();
              }
          }
  
          return account;
      }
  
      private Session getSession() {
          if (session == null){
              session = getSessionFactory().getCurrentSession();
          }
          return session;
      }
  }
  </code></pre>
  
  <p>The problem is just: When I access elements within the list "mailAccounts", I get the following exception:</p>
  
  <blockquote>
    <p>org.hibernate.LazyInitializationException:
    failed to lazily initialize a
    collection of role:
    test.account.UserAccount.mailAccounts,
    no session or session was closed</p>
  </blockquote>
  
  <p>I assume the reason for this exception is that the session got closed (don't know why and how) and thus Hibernate cannot load the list.
  As you can see, I even removed the <code>session.close()</code> call from the <code>loadUserAccount()</code> method but the session still seems to be either get closed or replaced by another instance.
  If I set <code>lazy=false</code>, then everything works smoothly but this is not what I wanted because I need the feature of loading data "on demand" due to performance issues.</p>
  
  <p>So, if I can't be sure that my session is still valid after the method <code>loadUserAccount(String username)</code> terminated, what's the point of having that feature and how do I work around that?</p>
  
  <p>Thanks for your help!</p>
  
  <p>Ps: I am a Hibernate beginner so please excuse my noobishness.</p>
  
  <p><strong>Update:</strong> Here is my hibernate config.cfg.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"&gt;
  &lt;hibernate-configuration&gt;
      &lt;session-factory&gt;
          &lt;property name="hibernate.connection.driver_class"&gt;com.mysql.jdbc.Driver&lt;/property&gt;
          &lt;property name="hibernate.connection.password"&gt;foo&lt;/property&gt;
          &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost:3306/mytable&lt;/property&gt;
          &lt;property name="hibernate.connection.username"&gt;user&lt;/property&gt;
          &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQLInnoDBDialect&lt;/property&gt;
  
          &lt;!-- Auto create tables --&gt;
  &lt;!--        &lt;property name="hbm2ddl.auto"&gt;create&lt;/property&gt;--&gt;
  
          &lt;!-- Enable Hibernate's automatic session context management --&gt;
          &lt;property name="current_session_context_class"&gt;thread&lt;/property&gt;
  
          &lt;!-- Mappings --&gt;
          &lt;mapping resource="test/account/SmampiAccount.hbm.xml"/&gt;
          &lt;mapping resource="test/account/MailAccount.hbm.xml"/&gt;
      &lt;/session-factory&gt;
  &lt;/hibernate-configuration&gt;
  </code></pre>