TheVillageIdiot
TheVillageIdiot

Reputation: 40497

org.hibernate.HibernateException: collection is not associated with any session

A friend of mine have got a peculiar problem in an open source software OscarMcmaster. He asked me to help and I am able to get to the code causing problem. The following is a method:

 public BillingService getBillingCodeByCode(String code){
    List list = billingServiceDao.findBillingCodesByCode( code,"BC");
    if(list == null || list.size() ==0 ){
        return null;
    }
    return (BillingService) list.get(0);
  }

The billingServiceDao is initialized by Spring container:

private static BillingServiceDao billingServiceDao = 
                  (BillingServiceDao) SpringUtils.getBean("billingServiceDao");

In BillingServiceDao class following code is executed:

public List<BillingService> findBillingCodesByCode(String code, String region) {
    Query query = entityManager.createQuery("select bs  from....");
    query.setParameter("code", code + "%");
    query.setParameter("region", region);

    @SuppressWarnings("unchecked")
    List<BillingService> list = query.getResultList();
    return list;
}

The culprit is query.getResultList(); but I'm from other universe (.Net) and don't know the remedy for the problem.

Please help me help my friend solve this problem.

EDIT:- Stack Trace

SEVERE: Servlet.service() for servlet action threw exception
org.hibernate.HibernateException: collection is not associated with any session
    at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)
    at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:797)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:241)
    at org.hibernate.loader.Loader.doList(Loader.java:2220)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
    at org.hibernate.loader.Loader.list(Loader.java:2099)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:66)
    at org.oscarehr.common.dao.BillingServiceDao.findBillingCodesByCode(BillingServiceDao.java:47)
    at org.oscarehr.common.dao.BillingServiceDao$$FastClassByCGLIB$$f613fb7e.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)

Upvotes: 6

Views: 21185

Answers (2)

th3morg
th3morg

Reputation: 4779

I was seeing this issue because I had failed to annotate a method in a service with @Transactional. It seems that Hibernate closes the session when a call to another method is made (even within the same class) unless the caller is annotated appropriately.

Upvotes: 0

bernerbrau
bernerbrau

Reputation: 363

By default, Hibernate populates list objects "lazily", and to do that you need an open session. Spring is opening and closing the Hibernate session around the call to the DAO. So when you go to inspect the list, Hibernate tries to populate it for you, but it finds that the session is closed and throws the error.

You need to add an OpenSessionInViewFilter to the web.xml (assuming you are writing a web app), add an OpenSessionInViewInterceptor to the spring context, or simply extract the list contents before returning them:

return new ArrayList<BillingService>(list);

Also as an aside, this:

private static BillingServiceDao billingServiceDao = 
              (BillingServiceDao) SpringUtils.getBean("billingServiceDao");

Totally defeats the purpose of using Spring in the first place.

Upvotes: 4

Related Questions