2014-08-27 49 views
0

一个有两个休眠实体和一个简单的1:N集合关系:同样,Hibernate.initialize失败org.hibernate.HibernateException:收藏不与任何会话相关

@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数据库中几乎所有的实体都可以正常工作,但有些(似乎是随机)失败,“org.hibernate.HibernateException:集合与任何会话都没有关联”。据我了解,发生这种情况是因为PersistentSet中的会话已关闭,但为什么它首先关闭?

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

什么可以关闭会话?有没有什么好的地方可以调试它(例如Hibernate中的某个断点)?

UPDATE:

我在位置类相互之间的关系:

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

它是空的失败的行,但它更改为@Transient使问题消失。

+0

你是如何处理Hibernate会话打开和关闭的? – heikkim 2014-08-27 07:31:47

+0

使用tx:注解驱动和org.springframework.orm.hibernate3.HibernateTransactionManager – ike3 2014-08-27 07:35:23

+0

在OpenSessionInView过滤器中有一个掠夺 – 2014-08-27 07:45:18

回答

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> 
0

这是definetely不是我的问题找到正确的答案足够的数据。对不起。

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

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

相关问题