Spring 集合的初始化引发LazyInitializationException
我在从Spring 集合的初始化引发LazyInitializationException,spring,hibernate,jsp,spring-mvc,lazy-initialization,Spring,Hibernate,Jsp,Spring Mvc,Lazy Initialization,我在从JSP文件访问集合时遇到问题。该应用程序基于MVC Spring框架。我将OpenSessionInViewFilter过滤器放入我的web.xml。当我想访问带有上述文件的URL时,它会抛出我 org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.app.cloud.hibernate.Product.availabilities,未关闭任何会话或会话 我在我的应用程序中使用域驱动设计。当我将classProduct中的fet
JSP
文件访问集合时遇到问题。该应用程序基于MVC Spring框架。我将OpenSessionInViewFilter
过滤器放入我的web.xml
。当我想访问带有上述文件的URL时,它会抛出我
org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.app.cloud.hibernate.Product.availabilities,未关闭任何会话或会话
我在我的应用程序中使用域驱动设计。当我将classProduct
中的fetch类型从FetchType.LAZY
更改为FetchType.EAGER
时,它起了作用
堆栈跟踪
web.xml
index.jsp
春天
org.springframework.web.servlet.DispatcherServlet
1.
春天
/
OpenSessionInViewFilter
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
sessionFactoryBeanName
会话工厂
单一会话
真的
OpenSessionInViewFilter
/*
log4jConfigLocation
WEB-INF/log4j.properties
log4jExposeWebAppRoot
假的
org.springframework.web.util.Log4jConfigListener
spring-servlet.xml
类路径:hibernate.cfg.xml
org.hibernate.cfg.AnnotationConfiguration
${jdbc.dial}
真的
ProductService.java
@Transactional
公共接口产品服务{
@交易的
公开作废添加(产品);
@交易的
公共列表getAll();
@交易的
公共产品get(整数idProduct);
@交易的
公共无效删除(整数id);
@交易的
公共作废编辑(产品);
}
ProductServiceImpl.java
@服务
@交易的
公共类ProductServiceImpl实现ProductService{
@自动连线
私人产品;
@交易的
公共无效添加(产品){
productDAO.add(产品);
}
@交易的
公共列表getAll(){
返回productDAO.getAll();
}
@交易的
公共无效删除(整数id){
productDAO.remove(id);
}
@交易的
公共产品获取(整数idProduct){
返回productDAO.get(idProduct);
}
@交易的
公共作废编辑(产品){
编辑(产品);
}
}
ProductDAO.java
公共接口产品DAO{
公开作废添加(产品);
公共作废编辑(产品);
公共列表getAll();
公共产品get(整数idProduct);
公共无效删除(整数id);
}
ProductDAOImpl.java
@存储库
公共类ProductDAOImpl实现ProductDAO{
@自动连线
私人会话工厂会话工厂;
公共无效添加(产品){
sessionFactory.getCurrentSession().save(产品);
}
公共列表getAll(){
返回sessionFactory.getCurrentSession().createQuery(“来自产品”)
.list();
}
公共无效删除(整数id){
产品产品=(产品)sessionFactory.getCurrentSession().load(
产品类别、标识);
if(null!=产品){
sessionFactory.getCurrentSession().delete(产品);
}
}
公共产品获取(整数idProduct){
产品产品=(产品)sessionFactory.openSession().get(
产品类别,idProduct);
退货产品;
}
@凌驾
公共作废编辑(产品){
sessionFactory.getCurrentSession()更新(产品);
}
}
Product.java
@实体
@表(name=“product”,catalog=“app”)
公共类产品实现java.io.Serializable{
私有整数idProduct;
@空空如也
@长度(最小值=1,最大值=70)
私有字符串名称;
私有集可用性=新哈希集(0);
公共产品(){
}
公共产品(字符串名称){
this.category=类别;
this.name=名称;
this.lastUpdate=lastUpdate;
this.actionFlag=actionFlag;
}
公共产品(字符串名称,
设置可用性,
) {
this.name=名称;
this.availabilities=可用性;
}
@身份证
@生成值(策略=标识)
@列(name=“id\u product”,unique=true,nullable=false)
公共整数getIdProduct(){
返回此.idProduct;
}
public void setIdProduct(整数idProduct){
this.idProduct=idProduct;
}
@列(name=“name”,null=false,长度=70)
公共字符串getName(){
返回此.name;
}
公共void集合名(字符串名){
this.name=名称;
}
@OneToMany(fetch=FetchType.LAZY,mappedBy=“product”)
公共集getAvailabilities(){
返回此。可用性;
}
公共无效设置可用性(设置可用性){
this.availabilities=可用性;
}
}
使用Hibernate时,这是一个非常典型的错误
如果您有任何延迟加载代理,在从@Transactional
上下文返回之前,您应该将它们替换为null或真实对象
延迟加载的集合
或列表
将被带有代理的Hibernate替换。代理将在首次访问集合时加载该集合。但是,如果您在事务上下文之外,第一次访问它会怎么样?代理引用的hibernate会话不存在,因此出现错误
如果不需要该集合,请将其设置为null或空HashSet/ArrayList。
如果需要,请调用size()
或在Transaction中遍历元素
SEVERE: Servlet.service() for servlet [spring] in context with path [] threw exception [org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.cloud.hibernate.Product.availabilities, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.cloud.hibernate.Product.availabilities, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119)
at org.hibernate.collection.PersistentSet.isEmpty(PersistentSet.java:169)
at org.apache.el.parser.AstEmpty.getValue(AstEmpty.java:55)
at org.apache.el.parser.AstNot.getValue(AstNot.java:44)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fwhen_005f0(products_jsp.java:321)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fchoose_005f0(products_jsp.java:290)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fforEach_005f0(products_jsp.java:233)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fif_005f0(products_jsp.java:185)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspService(products_jsp.java:141)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet._serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1686)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<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>
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Context parameters -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jExposeWebAppRoot</param-name>
<param-value>false</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
</web-app>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven />
<tx:annotation-driven />
<context:component-scan base-package="com.app.cloud" />
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="spring-views" />
<property name="order" value="1" />
</bean>
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2" />
</bean>
<!-- JDBC -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
<!-- Hibernate -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
@Transactional
public interface ProductService {
@Transactional
public void add(Product product);
@Transactional
public List<Product> getAll();
@Transactional
public Product get(Integer idProduct);
@Transactional
public void remove(Integer id);
@Transactional
public void edit(Product product);
}
@Service
@Transactional
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductDAO productDAO;
@Transactional
public void add(Product product) {
productDAO.add(product);
}
@Transactional
public List<Product> getAll() {
return productDAO.getAll();
}
@Transactional
public void remove(Integer id) {
productDAO.remove(id);
}
@Transactional
public Product get(Integer idProduct) {
return productDAO.get(idProduct);
}
@Transactional
public void edit(Product product) {
productDAO.edit(product);
}
}
public interface ProductDAO {
public void add(Product product);
public void edit(Product product);
public List<Product> getAll();
public Product get(Integer idProduct);
public void remove(Integer id);
}
@Repository
public class ProductDAOImpl implements ProductDAO {
@Autowired
private SessionFactory sessionFactory;
public void add(Product product) {
sessionFactory.getCurrentSession().save(product);
}
public List<Product> getAll() {
return sessionFactory.getCurrentSession().createQuery("from Product")
.list();
}
public void remove(Integer id) {
Product product = (Product) sessionFactory.getCurrentSession().load(
Product.class, id);
if (null != product) {
sessionFactory.getCurrentSession().delete(product);
}
}
public Product get(Integer idProduct) {
Product product = (Product) sessionFactory.openSession().get(
Product.class, idProduct);
return product;
}
@Override
public void edit(Product product) {
sessionFactory.getCurrentSession().update(product);
}
}
@Entity
@Table(name = "product", catalog = "app")
public class Product implements java.io.Serializable {
private Integer idProduct;
@NotEmpty
@Length (min=1,max=70)
private String name;
private Set<Availability> availabilities = new HashSet<Availability>(0);
public Product() {
}
public Product(String name) {
this.category = category;
this.name = name;
this.lastUpdate = lastUpdate;
this.actionFlag = actionFlag;
}
public Product(String name,
Set<Availability> availabilities,
) {
this.name = name;
this.availabilities = availabilities;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id_product", unique = true, nullable = false)
public Integer getIdProduct() {
return this.idProduct;
}
public void setIdProduct(Integer idProduct) {
this.idProduct = idProduct;
}
@Column(name = "name", nullable = false, length = 70)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "product")
public Set<Availability> getAvailabilities() {
return this.availabilities;
}
public void setAvailabilities(Set<Availability> availabilities) {
this.availabilities = availabilities;
}
}
@Proxy (lazy = false)