3

我正在使用 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=false”,一切正常,但是一旦我切换到“lazy=true”,它就会给我以下错误:

org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.lifepin.entities.PinboardEntry.comments,没有会话或会话已关闭

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

谢谢!

4

4 回答 4

3

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

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

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

于 2009-04-23T07:28:00.240 回答
1

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

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

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

于 2009-06-09T07:39:28.037 回答
0

有些人在使用带有 Spring 框架的休眠时使用 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>

但这并不能解决我的问题。也许我做错了什么。

于 2009-06-09T07:26:26.783 回答
0

这是因为您的 Hibernate 会话在 getHibernateTemplate 方法的某处被关闭,如果您有lazy="true",则可以在 seesion.open() 和 session.close() 之间实例化关联。lazy="false" 正在工作,因为 Hibernate 在加载 A 时急切地获取关联的 B 对象。

于 2009-05-15T18:28:53.157 回答