Hibernate:延迟加载不会';t在集合上处理一对多映射

Hibernate:延迟加载不会';t在集合上处理一对多映射,hibernate,spring,spring-mvc,Hibernate,Spring,Spring Mvc,我正在使用Spring和Hibernate为Liferay portal服务器开发一个Portlet。我现在基本上有两个实体,A和B,其中A可能包含许多B。这是二者之间的一对多映射 <set cascade="all" lazy="true" name="comments" order-by="creationDate desc"> <key column="lfpn_pinboardentries_idPinboardEntry" not-null="true"/>

我正在使用Spring和Hibernate为Liferay portal服务器开发一个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>
如果我有“lazy=false”,一切都正常,但一旦我切换到“lazy=true”,就会出现以下错误:

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

有没有人对可能出现的问题或如何解决问题提出建议


谢谢

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

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


您必须将对象重新加载到当前Hibernate会话中才能延迟加载属性这是因为您的Hibernate会话正在getHibernateTemplate方法中的某个位置关闭,如果您具有lazy=“true”,则可以在seision.open()和session.close()之间实例化关联。
lazy=“false”起作用是因为Hibernate在加载A时急切地获取关联的B对象。

有些人在使用Hibernate with spring framework时使用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>

openSessionInViewFilter
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
openSessionInViewFilter
/*

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

关于hibernate延迟加载的讨论和一个非常有用的解决方案(称为预加载模式)可以在这里找到:

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


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

我认为问题不在于请求,因为我在单元测试中遇到了相同的问题,在单元测试中,我只是加载父对象,然后在尝试访问嵌入的延迟加载对象列表时,它崩溃了,给我上面的错误消息。在我看来,在访问延迟加载的集合之前,您的初始hibernate会话仍然处于关闭状态。打开日志以进行验证。另一件需要注意的事情是Spring的事务配置&您的方法是否使用了[transaction()]属性?我现在打开了Spring的HibernateTransactionManager,并在我的服务类之前添加了org.springframework.transaction.interceptor.TransactionProxyFactoryBean…仍然存在相同的问题:(我更愿意说:在访问惰性集合之前,您需要打开会话并通过
session.merge()
将对象与会话重新关联。或者,您可以使用
session.lock(myA)
+
Hibernate\35; initialize(myA.getComments())
。你的英语真的很难读!我知道问题是我的会话在某个地方被关闭了(这也是错误消息所说的),因此延迟加载显然不起作用。但问题是,我如何避免会话被关闭。我说德语,所以没问题:)我来看看,谢谢
<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>