OpenSessionInView模式
Spring+Hibernate中, 集合映射如果使用lazy="true", 当PO传到View层时, 出现未初始化session已关闭的错误,只能在dao先初始化
parent.getChilds().size();
Spring提供Open Session In View来解决这个问题, 有两种方式
1. Interceptor
<
bean
id
="urlMapping"
class
="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"
>
< property name ="interceptors" >
< list >
< ref bean ="openSessionInViewInterceptor" />
</ list >
</ property >
< property name ="mappings" >
.
</ property >
</ bean >
< bean id ="openSessionInViewInterceptor"
class ="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
< property name ="interceptors" >
< list >
< ref bean ="openSessionInViewInterceptor" />
</ list >
</ property >
< property name ="mappings" >
.
</ property >
</ bean >
< bean id ="openSessionInViewInterceptor"
class ="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
<
web-app
>
< filter >
< filter-name > hibernateFilter </ filter-name >
< filter-class >
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</ filter-class >
</ filter >
< filter-mapping >
< filter-name > hibernateFilter </ filter-name >
< url-pattern > *.do </ url-pattern >
</ filter-mapping >
</ web-app >
< filter >
< filter-name > hibernateFilter </ filter-name >
< filter-class >
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</ filter-class >
</ filter >
< filter-mapping >
< filter-name > hibernateFilter </ filter-name >
< url-pattern > *.do </ url-pattern >
</ filter-mapping >
</ web-app >
说明: 个人更喜欢用Interceptor方式, filter是在web.xml中定义
有了OpenSessionInView,并不是一切就ok了。简单的crud可以,但对于复杂业务逻辑就要想点法子。
OSIV默认是request per session的, 所以即使没有显式update(po),Hibernate也会帮你保存的,dao的业务判断就无效,还好有evict()可用。
update code
Controller
public ModelAndView update() {
p = dao.getVo(id);
bindObject(request);
dao.update(p);
}
Dao
public Object getVo(id) {
p = getHibernateTemplate().get(clazz, id);
p.getChilds().size();
getHibernateTemplate().evict(p);
return p;
}
public void update(p) {
oldP = getVo(id);
// ++--(oldP);
getHibernateTemplate().update(p);
// ++--(p);
}
public ModelAndView update() {
p = dao.getVo(id);
bindObject(request);
dao.update(p);
}
Dao
public Object getVo(id) {
p = getHibernateTemplate().get(clazz, id);
p.getChilds().size();
getHibernateTemplate().evict(p);
return p;
}
public void update(p) {
oldP = getVo(id);
// ++--(oldP);
getHibernateTemplate().update(p);
// ++--(p);
}
本文详细介绍了Spring+Hibernate中OpenSessionInView模式的两种实现方式,包括Interceptor和Filter,并讨论了如何处理复杂的业务逻辑以避免未初始化session已关闭的错误。
898

被折叠的 条评论
为什么被折叠?



