Hibernate:延迟加载不适用于set上的一对多映射

时间:2009-04-23 07:05:36

标签: hibernate spring spring-mvc

我正在将Spring与Hibernate一起用于为Liferay门户服务器开发Portlet。我现在基本上有两个实体,A和B,其中A可能包含许多B。所以这是两者之间的一对多映射。

<set cascade="all" lazy="true" name="comments" order-by="creationDate desc">
   <key column="lfpn_pinboardentries_idPinboardEntry" not-null="true"/>
   <one-to-many class="Comment"/>
</set>

在DAO层的实体A的相应DAO中,我继承了spring提供的“HibernateDaoSupport”,因此典型的数据检索如下所示:

...
public A getA(long id) {
  return (A) getHibernateTemplate().get(A.class, id);
}
...

如果我有“懒惰=假”,一切正常,但是当我切换到“lazy = true”时,它会给我以下错误:

org.hibernate.LazyInitializationException:懒得初始化角色集合:com.lifepin.entities.PinboardEntry.comments,没有关闭会话或会话

有没有人有什么建议可能是问题或提示如何解决?

谢谢!

4 个答案:

答案 0 :(得分:3)

如果您在一个请求中加载了对象,那么通常会收到此错误,然后在不访问延迟加载的属性的情况下,将对象保存在会话中。如果您在另一个请求中尝试访问延迟加载的属性,您将获得此异常。

简单地说:最初加载对象的Hibernate会话已关闭。在不同的Hibernate会话中访问此对象的延迟加载属性时会导致此异常。

您必须将对象重新加载到当前的Hibernate会话中才能延迟加载属性

答案 1 :(得分:1)

关于hibernate延迟加载的一个很好的讨论和一个非常有用的解决方案(称为预加载模式)可以在这里找到: http://entwickler-forum.de/showthread.php?t=47067

不幸的是,这是一个德国网站。但至少源代码及其文档是英文的。

上述网站的核心思想是提供机会避免加载整个对象图(通过延迟加载)并明确指定在给定情况下应加载对象图的哪些部分。

答案 2 :(得分:0)

这是因为你的Hibernate会话在getHibernateTemplate方法的某个地方关闭了,如果你有lazy =“true”,那么可以在seesion.open()和session.close()之间实例化关联。 lazy =“false”正在运行,因为Hibernate在加载A时急切地获取关联的B对象。

答案 3 :(得分:0)

有些人在使用带弹簧框架的hibernate时使用OpenSessionInViewFilter。

它说您必须在web.xml文件中声明过滤器:

<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>openSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

但它并没有解决我的问题。也许我做错了什么。