title: Hibernate "failed to lazily initialize a collection" runtime error
body: <p>This question has been asked many times, but I still can't find a solution for my use case:</p>
  
  <ol>
  <li><p>I have a Struts2 application using Hibernate 5.x.</p></li>
  <li><p>The application is a "Contacts app".  It has two entities: a "Contact", which can have zero or more "Notes".</p></li>
  <li><p>Here's how I get the contacts:</p>
  
  <pre><code>@Override
  public List&lt;Contact&gt; getContacts() {
  //Note: Hibernate 5++ supports Java try-with-resource blocks
  try (Session session = HibernateUtil.openSession()) {
      List&lt;Contact&gt; contacts = session.createQuery("FROM Contact").list();
      return contacts;
      ...
  </code></pre></li>
  <li><p>It works great.  Until I try something like this:</p>
  
  <pre><code>ObjectMapper mapper = new ObjectMapper();
  jsonString = mapper.writeValueAsString(contacts);
  </code></pre></li>
  </ol>
  
  <p><strong>ERROR:</strong></p>
  
  <pre><code>16:05:16.174 [http-nio-8080-exec-2] DEBUG org.apache.struts2.dispatcher.Dispatcher - Dispatcher serviceAction failed
  com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.example.contactsapp.models.Contact.notes, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]-&gt;com.example.contactsapp.models.Contact["notes"])
      at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394) ~[jackson-databind-2.10.0.jar:2.10.0]
      ...
      at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4094) ~[jackson-databind-2.10.0.jar:2.10.0]
      at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3404) ~[jackson-databind-2.10.0.jar:2.10.0]
      at com.example.contactsapp.actions.ContactsAction.getContacts(ContactsAction.java:36) ~[classes/:?]
      ...
  </code></pre>
  
  <p><strong>POSSIBLE SOLUTIONS</strong></p>
  
  <ol>
  <li><p>I do <em>NOT</em> want to change to <code>FetchType.Eager</code>.</p></li>
  <li><p>Since I'm not using Spring, I can't use <code>@Transactional</code> or <code>OpenSessionInView</code>.  But I'd love if there were equivalents for Hibernate-only.</p></li>
  <li><p>These are the things I've tried (based largely on <a href="https://stackoverflow.com/a/42206232/3135317">How to solve the “failed to lazily initialize a collection of role” Hibernate exception</a>):</p>
  
  <pre><code>@Override
  public List&lt;Contact&gt; getContactsFetchAll() {
    //Note: Hibernate 5++ supports Java try-with-resource blocks
    try (Session session = HibernateUtil.openSession()) {
      // Jackson mapper.writeValueAsString() =&gt; "failed to lazily initialize a collection" 
      // List&lt;Contact&gt; contacts = session.createQuery("FROM Contact").list();
  
      // Plan A: Causes same "failed to lazily initialize a collection" runtime error
      // List&lt;Contact&gt; contacts = session.createQuery("FROM Contact").list();
      // Hibernate.initialize(contacts);
  
      // Plan B: Still no-go: returns [] empty set
      // List&lt;Contact&gt; contacts = session.createQuery("SELECT c FROM Contact c JOIN FETCH c.notes n").list();
  
      // Plan C: Same: "failed to lazily initialize a collection of role..."
      // Query query = session.createQuery("FROM Contact");
      // Hibernate.initialize(query);
      // List&lt;Contact&gt; contacts = query.list(); 
  
      // Plan D: Same: "ERROR: failed to lazily initialize a collection of role"
      // List&lt;Contact&gt; contacts = session.createQuery("FROM Contact").list();
      // for (Contact c : contacts) {
      //    Set&lt;Note&gt; n = c.getNotes();
      // }
         return contacts;
      }
   }
  </code></pre></li>
  </ol>
  
  <p>Q: Any suggestions?</p>
  
  <p>Q: Do you need any additional information?</p>
  
  <hr>
  
  <p>I've done a bit more research.  </p>
  
  <p>Apparently, in this particular scenario, Hibernate doesn't do a "join" at all. </p>
  
  <p>Instead:</p>
  
  <ol>
  <li>It does a "select" to get the parent.  </li>
  <li>If you try to <em>read</em> something from any of the children, then it does <em>ANOTHER</em> "select", to get the children.  One "select" for the parent, a second for the children.  </li>
  <li>If the entity is configured for "eager fetch", it <em>always</em> does all selects up-front.  </li>
  <li>For "lazy fetch", you <em>MUST</em> try to read the children (thus triggering the second select) before closing the session.  Otherwise, if you try to read the child data after the session closes, you get "failed to lazily initialize a collection".</li>
  <li>A Left Join doesn't work in this scenario: the result set returned by the database simply doesn't match the entity.  To make it work, I'd have to read the result set a row at a time, and build the entity manually.</li>
  <li>I'm still looking for a way to get "Join Fetch" to work in my scenario...</li>
  </ol>