我在使用 Spring 3/Hibernate 3.6 和 jsp 的 Web 应用程序中遇到了可怕的 LazyInitializationException。我的 web.xml 中有 OpenSessionInViewFilter,但我的 HSession 似乎仍然以某种方式关闭或失效。我还检查了我的应用程序没有引起异常。
这是我的 web.xml
<filter>
<filter-name>hibernateFilter</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>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<servlet-name>hedgebenefits</servlet-name>
</filter-mapping>
Context.xml 是:
<mvc:annotation-driven/>
<tx:annotation-driven/>
<context:component-scan base-package="com.hedgebenefits.*"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/managerie"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="namingStrategy" class="org.hibernate.cfg.ImprovedNamingStrategy"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="com.hedgebenefits.domain"/>
<property name="dataSource" ref="dataSource"/>
<property name="namingStrategy" ref="namingStrategy"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
</value>
</property>
</bean>
jsp是:
<tr>
The list is :
<td>
<c:forEach var="admin" items="${admins}">
Admin is ${admin.username},
<c:forEach var="sector" items="${admin.sectors}">
sector is ${sector.name}
</c:forEach>
</c:forEach>
</td>
</tr>
服务使用@Transactional 注释:
@Service
@Transactional
public class AdminServiceImpl implements AdminService {
private AdminDao adminDao;
@Autowired
public AdminServiceImpl(AdminDao adminDao) {
this.adminDao = adminDao;
}
...
@Override
public List<Admin> listAllAdmins() {
return adminDao.listAllAdmins();
}
}
道是:
@Repository
public class AdminDaoImpl implements AdminDao{
private SessionFactory sessionFactory;
@Autowired
public AdminDaoImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
....
@Override
public List<Admin> listAllAdmins() {
List<Admin> adminList = sessionFactory.getCurrentSession().createCriteria(Admin.class)
.setMaxResults(5)
.list();
return adminList;
}
}
编辑:添加了控制器和堆栈跟踪
控制器是:
@Controller
@RequestMapping(value = "/admin")
@SessionAttributes(value = "admin")
public class AdminRegistrationController {
...
@Autowired
private AdminService adminService;
@RequestMapping(value = "/list")
public ModelAndView listRegisteredAdmins() {
List<Admin> admins = adminService.listAllAdmins();
return new ModelAndView(LIST_ADMINS.getViewName()).addObject("admins", admins);
}
堆栈跟踪是:
org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/jsp/list.jsp at line 15
12: <td>
13: <c:forEach var="admin" items="${admins}">
14: Admin is ${admin.username},
15: <c:forEach var="sector" items="${admin.sectors}">
16: sector is ${sector.name}
17: </c:forEach>
18: </c:forEach>
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:521)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:430)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1157)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:927)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.hedgebenefits.domain.Admin.sectors, no session or session was closed
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:348)
org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:224)
org.apache.taglibs.standard.tag.common.core.ForEachSupport.prepare(ForEachSupport.java:155)
javax.servlet.jsp.jstl.core.LoopTagSupport.doStartTag(LoopTagSupport.java:256)
org.apache.jsp.WEB_002dINF.jsp.list_jsp._jspx_meth_c_005fforEach_005f1(list_jsp.java:149)
org.apache.jsp.WEB_002dINF.jsp.list_jsp._jspx_meth_c_005fforEach_005f0(list_jsp.java:112)
org.apache.jsp.WEB_002dINF.jsp.list_jsp._jspService(list_jsp.java:70)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1157)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:927)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
似乎我在这里遗漏了一些明显的东西,但不知道是什么?