Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 917
TheVillageIdiot Avatar asked Jan 05 '12 18:01

TheVillageIdiot


1 Answers

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.

like image 178
bernerbrau Avatar answered Oct 30 '22 00:10

bernerbrau