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,未关闭任何会话或会话

我在我的应用程序中使用域驱动设计。当我将class
Product
中的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)