Hibernate.initialize因org.hibernate.HibernateException而失败:collection与任何会话无关

时间:2014-08-27 07:28:09

标签: java spring hibernate

A有两个hibernate实体和一个简单的1:N集合关系:

@Entity
public class Root {
    @OneToMany(mappedBy = "root", fetch = FetchType.LAZY)
    public Set<Position> getPositions() {
        return positions;
    }
}

并且Spring MVC Web应用程序加载根实体并初始化延迟集合:

@Transactional
public Root findFullById(Long id) {
    Root root = (Root) getSession().get(Root.class, id);
    Hibernate.initialize(root.getPositions()); // this line fails
    return root;
}

此方法之前有 NO 数据库操作。

这适用于我的Oracle 11 DB中的几乎所有实体,但有些(似乎是随机的)使用&#34; org.hibernate.HibernateException失败:集合与任何会话都没有关联#34;。据我所知,这是因为PersistentSet中的会话已关闭,但为什么它首先关闭?

最奇怪的是,如果我在这一行放置一个断点并在调试器中调用Hibernate.initialize()(即在eclipse Inspect窗口中),它会成功加载该集合。

什么可以关闭会话?是否有任何好的调试地点(即Hibernate中的断点)?

更新

我在Position课程中有另一种关系:

@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "POSITION_NUMBER", referencedColumnName = "POSITION_NUMBER", insertable = false, updatable = false)
public Set<Child> getChildren() {
    return children;
}

对于失败的行,它是空的,但将其更改为@Transient会使问题消失。

2 个答案:

答案 0 :(得分:0)

您可能需要使用OpenSessionInViewFilter来处理会话打开和关闭。您没有指定Spring / Hibernate版本,因此可能需要进行调整。

web.xml过滤器定义:

<filter>    
    <filter-name>hibernateFilter</filter-name>
      <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
      <init-param>
         <param-name>sessionFactoryBeanName</param-name>
         <param-value>sessionFactory</param-value>         
      </init-param>      
   </filter>

   <filter-mapping>
     <filter-name>hibernateFilter</filter-name>
   <url-pattern>
</filter>

答案 1 :(得分:0)

在我的问题中定义的数据不足以找到正确的答案。对不起。

所以与社区分享我的经验:问题是第二个密钥(POSITION_NUMBER)在第一个集合中不是唯一的,所以hibernate加载了这个集合两次,第二次初始化失败。不知道在调试器中是什么使得它没问题,但是修复数据解决了这个问题。

所以我真正缺少的是关键列的唯一约束。