org.hibernate.HibernateException:collection与任何会话无关

The*_*iot 6 java spring hibernate

我的一个朋友在开源软件中遇到了一个奇怪的问题OscarMcmaster.他让我帮忙,我能够解决造成问题的代码.以下是一种方法:

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

billingServiceDao被初始化Spring的容器:

private static BillingServiceDao billingServiceDao = 
                  (BillingServiceDao) SpringUtils.getBean("billingServiceDao");
Run Code Online (Sandbox Code Playgroud)

BillingServiceDao类中执行以下代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

罪魁祸首是query.getResultList();我来自其他宇宙(.Net)并且不知道问题的补救措施.

请帮我帮朋友解决这个问题.

编辑: - 堆栈跟踪

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)
Run Code Online (Sandbox Code Playgroud)

ber*_*rau 4

默认情况下,Hibernate 会“延迟”填充列表对象,为此您需要一个打开的会话。Spring 围绕 DAO 调用打开和关闭 Hibernate 会话。因此,当您检查列表时,Hibernate 会尝试为您填充它,但它发现会话已关闭并抛出错误。

您需要将 OpenSessionInViewFilter 添加到 web.xml (假设您正在编写一个 Web 应用程序),将 OpenSessionInViewInterceptor 添加到 spring 上下文,或者在返回列表内容之前简单地提取列表内容:

return new ArrayList<BillingService>(list);
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这个:

private static BillingServiceDao billingServiceDao = 
              (BillingServiceDao) SpringUtils.getBean("billingServiceDao");
Run Code Online (Sandbox Code Playgroud)

完全违背了使用 Spring 的初衷。