2011-12-08 31 views
1

我使用hibernate和jsp-servlet。當我試圖訪問子元素屬性時,我收到以下異常:Hibernate org.hibernate.LazyInitializationException

Servlet.service() for servlet jsp threw exception: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.ecomm.ultimatesms.messaging.persistence.pojos.Mno.startnumbers, no session or session was closed 
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380) [:3.3.2.GA] 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372) [:3.3.2.GA] 
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365) [:3.3.2.GA] 
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108) [:3.3.2.GA] 

這是我的hibernate映射文件。我使用hibernate-mappingdefault-lazy="false"

<hibernate-mapping default-lazy="false"> 
<class name="com.ecomm.ultimatesms.messaging.persistence.pojos.Mno" table="mno" schema="public"> 

    <id name="pkmnoid" type="long"> 
     <column name="pkmnoid" /> 
    <generator class="sequence"> 
      <param name="sequence">mno_pkmnoid_seq1</param> 
     </generator> 
    </id> 

    <property name="name" type="string"> 
     <column name="name" length="45" /> 
    </property> 

    <set name="startnumbers" table="startnumber" inverse="false" lazy="true" fetch="select" cascade="delete"> 
     <key> 
      <column name="fkmnoid" /> 
     </key> 
     <one-to-many class="com.ecomm.ultimatesms.messaging.persistence.pojos.Startnumber" /> 
    </set> 
</class> 
</hibernate-mapping> 

回答

1

一個很好的方式來授予你仍然有一個打開的會話/實體管理器打開是有一個過濾器在請求開始時注入EntityManager而不是在它的執行結束後關閉它所以你再也不會在乎它了。看看

package com.renatogama.infra.filters; 

import java.io.IOException; 

import javax.persistence.EntityManager; 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.annotation.WebFilter; 

@WebFilter(urlPatterns = "/*") 
public class EntityManagerFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException { 
     EntityManager em = new JPAUtil().getEntityManager(); 
     try { 
      em.getTransaction().begin(); 
      request.setAttribute("em", em); 
      chain.doFilter(request, response); 
      em.getTransaction().commit(); 
     } catch (Exception e) { 
      em.getTransaction().rollback(); 
      throw new ServletException(e); 
     } finally { 
      em.close(); 
     } 
    } 

    @Override 
    public void destroy() {} 

    @Override 
    public void init(FilterConfig arg0) throws ServletException {} 
} 
0

雖然你設置lazy='true',你描述的,你把它設置爲false。因此,在訪問該集合之前會話已關閉導致問題(startnumbers)。通過設置lazy='false'(或)使用Hibernate.initialize() api在會話關閉(或)使用Open-Session-In-View模式之前加載集合來更改映射。

相關問題