LazyInitializationException:未能延迟初始化角色集合无法初始化代理 - 无会话
LazyInitializationException: failed to lazily initialize a collection of role could not initialize proxy - no Session
这在 SO 中被问了很多次。但是他们没有解决我的问题所以再次发帖。
尝试访问我的应用程序时出现以下异常
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.wpt.models.Item.itemCategory, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:348)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:224)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.prepare(ForEachSupport.java:155)
at javax.servlet.jsp.jstl.core.LoopTagSupport.doStartTag(LoopTagSupport.java:256)
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>hibernate4AnnotatedSessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Spring 配置:
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="hibernate4AnnotatedSessionFactory">
</bean>
Item.java
@Entity
@Table(name="item")
public class Item {
@OneToMany(mappedBy="item", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
private List<ItemCategory> itemCategory = new ArrayList<ItemCategory>();
}
ItemServiceImpl.java
@Override
@Transactional(readOnly=true)
public List<Item> getItemsByCategory(int categoryId) {
return itemDAO.getItemsByCategory(categoryId);
}
在所有博客中,建议使用 EAGER
获取,或使用 OpenSessionInViewFilter
并提供 @Transactional
支持。
如果我使用 EAGER
fetch,它将起作用。但不是以其他方式工作。我已经使用 @Transactional
注释实现了所有服务方法。我在这里犯了什么错误?有人可以帮忙吗?
首先你已经意识到如果你进行急切的获取会发生什么。这意味着当您请求项目时,对数据库的查询总是带上 itemCategory。也许这不是您期望的行为。
其次,lazyInitialization 异常发生是因为您试图在关闭会话后访问对象itemCategory。我想当您从方法 "getItemsByCategorymethod".
收到列表时会话已关闭
我通常解决这种情况的方式(不是做eager fetch)有两种方式:
在关闭会话之前选择 itemCategory。无论你在哪里调用执行查询,你都应该可以说 List listItemCategroy = item.getItemCategory()
.
将fetch.JOIN添加到table itemCategory,它会带来ItemCategory。
如果你想避免这个错误,你可以在你的代码中添加:
if (Hibernate.isInitilized()){
....
}
如果对象已初始化,它将 return 为真,否则为假。
好吧,经过一番努力,我终于找到了解决这个问题的方法。
我将 contextConfigLocation
添加到 DispatcherServlet's <init-param>
后问题得到解决。更改后,我的 DispatcherServlet
配置如下所示。
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
参考:This post
contextConfigLocation 用于指示 xml 文件(例如 Spring、spring-security)所在的位置。
惰性问题对我来说 Spring 配置没有任何意义。
能详细解释一下吗?
使用下面的过滤器而不是 HibernateFilter
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
希望对您有所帮助。
这在 SO 中被问了很多次。但是他们没有解决我的问题所以再次发帖。
尝试访问我的应用程序时出现以下异常
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.wpt.models.Item.itemCategory, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:348)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:224)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.prepare(ForEachSupport.java:155)
at javax.servlet.jsp.jstl.core.LoopTagSupport.doStartTag(LoopTagSupport.java:256)
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>hibernate4AnnotatedSessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Spring 配置:
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="hibernate4AnnotatedSessionFactory">
</bean>
Item.java
@Entity
@Table(name="item")
public class Item {
@OneToMany(mappedBy="item", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
private List<ItemCategory> itemCategory = new ArrayList<ItemCategory>();
}
ItemServiceImpl.java
@Override
@Transactional(readOnly=true)
public List<Item> getItemsByCategory(int categoryId) {
return itemDAO.getItemsByCategory(categoryId);
}
在所有博客中,建议使用 EAGER
获取,或使用 OpenSessionInViewFilter
并提供 @Transactional
支持。
如果我使用 EAGER
fetch,它将起作用。但不是以其他方式工作。我已经使用 @Transactional
注释实现了所有服务方法。我在这里犯了什么错误?有人可以帮忙吗?
首先你已经意识到如果你进行急切的获取会发生什么。这意味着当您请求项目时,对数据库的查询总是带上 itemCategory。也许这不是您期望的行为。
其次,lazyInitialization 异常发生是因为您试图在关闭会话后访问对象itemCategory。我想当您从方法 "getItemsByCategorymethod".
收到列表时会话已关闭我通常解决这种情况的方式(不是做eager fetch)有两种方式:
在关闭会话之前选择 itemCategory。无论你在哪里调用执行查询,你都应该可以说
List listItemCategroy = item.getItemCategory()
.将fetch.JOIN添加到table itemCategory,它会带来ItemCategory。
如果你想避免这个错误,你可以在你的代码中添加:
if (Hibernate.isInitilized()){
....
}
如果对象已初始化,它将 return 为真,否则为假。
好吧,经过一番努力,我终于找到了解决这个问题的方法。
我将 contextConfigLocation
添加到 DispatcherServlet's <init-param>
后问题得到解决。更改后,我的 DispatcherServlet
配置如下所示。
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
参考:This post
contextConfigLocation 用于指示 xml 文件(例如 Spring、spring-security)所在的位置。
惰性问题对我来说 Spring 配置没有任何意义。
能详细解释一下吗?
使用下面的过滤器而不是 HibernateFilter
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
希望对您有所帮助。