我正在使用jsp-servlet的hibernate。当我尝试访问子元素属性时,我得到以下异常:
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-mapping
default-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>
答案 0 :(得分:2)
我认为您不需要将所有连接设置为EAGER。
或者,您需要在视图模式中使用Open Session。
您可以在此处详细了解:
答案 1 :(得分: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 {}
}
答案 2 :(得分:0)
由于您已设置lazy=true
,因此必须在关闭hibernate会话之前初始化集合。这篇文章可能对您有所帮助http://community.jboss.org/wiki/LazyInitializationExceptionovercome
答案 3 :(得分:0)
虽然您设置了lazy='true'
,但您描述的是将其设置为false
。因此,在访问集合(startnumbers
)之前会导致问题导致会话关闭。通过设置lazy='false'
(或)使用Hibernate.initialize()
api在会话关闭(或)使用Open-Session-In-View
模式之前加载集合来更改映射。