Hello All,
How can I cache a query for an object with children that are lazily fetched?  I am defining the collection as LAZY fetch and retrieving the children via a "left join fetch" in the query.  
When I set hibernate.cache.use_query_cache to false, everything works great.  When I enable ehcache, it works the first time, but the 2nd time I load the page, I get the exception "failed to lazily initialize a collection, " presumably because it's retrieving the data from the cache.  The error specifically happens when a facelet in my view loops through the children to print them.  
I can get the error to go away if I loop through the collection and call any method in each child while still in the DAO that performs the query.
Surely, I am missing something.  
Any suggestions would be greatly appreciated.  
I have an application using Hibernate 3.3 through Spring 2.5 and JPA.  
My exception is:
Code:
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: mydomain.MyObject.replies, no session or session was closed
   at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
   at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
   at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:97)
   at org.hibernate.collection.PersistentBag.size(PersistentBag.java:225)
   at com.sun.facelets.tag.jstl.fn.JstlFunction.length(JstlFunction.java:88)
 
My bean is listed below.  I am using the named query listed below, MyObject.BY_UUID.
Code:
@Table(name = "my_table")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NamedQueries( {
      @NamedQuery(name = MyObject.BY_UUID, query = "from MyObject g left join fetch g.replies  where g.uuid in (:uids)", hints = @QueryHint(name = "org.hibernate.cacheable", value = "true")) })
public class MyObject  {
   public static final String BY_UUID = "BY_UUID";
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private int id;
   private String title;
   private String uuid;
   @OneToMany(cascade = CascadeType.MERGE)
   @JoinTable(name = "my_table_comment", inverseJoinColumns = @JoinColumn(name = "reply_id"))
   @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
   private List<Comment> replies = new ArrayList<Comment>();
//getters and setters
}
My persistence.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
   version="1.0">
   <persistence-unit name="grants">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
         <property name="hibernate.show_sql" value="true" />
         <!-- 2nd level cache  -->
         <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
         <property name="hibernate.cache.provider_configuration" value="/ehcache.xml" />
         <property name="hibernate.cache.use_second_level_cache" value="true" />
         <property name="hibernate.cache.use_query_cache" value="true" />
         <property name="hibernate.generate_statistics" value="true" />
         <property name="hibernate.cache.use_structured_entries" value="true" />
      </properties>
   </persistence-unit>
</persistence>
My DAO:
Code:
@Repository
@Transactional
public class MyObjectDAO{
   public Grant findMyObjectByGUID(String guid) {   
      MyObject obj =  namedQueryWithSingleResult(MyObject.BY_UUID, "uid", guid);
      ehcacheHack(obj);
      return obj;
   }
   private void ehcacheHack(MyObject grant) {
      logger.debug("I was called");
      for(Comment c : grant.getReplies()){   //ehcache hack.  Calling collection while session is open stops lazy init exception
         c.getId();
      }
   }
   public <K, E> E namedQueryWithSingleResult(String queryName, String columnName, K key) {
      Query qry = em.createNamedQuery(queryName);
      qry.setParameter(columnName, key);
      qry.setHint("org.hibernate.cacheable", true);
      return (E) qry.getSingleResult();
   }
Any helps is greatly appreciated.