struts2 里面OpenSessionInViewFilter
一定要写在最上面 下面有讲解
---------------------------------------------------------------
1、说说为什么使用lazy
当使用Hibernate中的one-to-many、many-to one、many-to-many关系映射的时候,一个对象中会包含一个或多个Set来关联其他的对象。例如:user-groups,当程序取user 对象时,如果一个用户有多个自定义组,那么程序将把组的信息也读取出来,在log中可以看到两个sql的输出。但是在页面的显示上,也许并不需要显示这个 用户相关组的信息,这样系统的消耗就白白浪费了,于是hibernate提供了lazy(延迟加载)的方法来避免这一情况的发生,我们只需要在 user.hbm.xml中设置lazy=true,就能实现延迟加载。
代码
<set name="groupses" table="usergroups" catalog="many" cascade="save-update" lazy="true">
<key>
<column name="userid" length="32" not-null="true" />
</key>
<many-to-many entity-name="com.example.model.Groups">
<column name="groupid" length="32" not-null="true" />
</many-to-many>
</set>
2、说说为什么使用OpenSessionInView
当hibernate+spring配合使用的时候,如果设置了lazy=true,那么在读取数据的时候,当读取了父数据后,hibernate 会自动关闭session,这样,当要使用子数据的时候,系统会抛出lazyinit的错误,这时就需要使用spring提供的 OpenSessionInViewFilter,
OpenSessionInViewFilter主要是保持Session状态知道request将全部页面发送到客户端,这样就可以解决延迟加载带来的问题
3、说说Webwork中使用OpenSessionInView的注意事项
web.xml中的配置要注意先后顺序,OpenSessionInViewFilter要在Webwork的filter前面,否则系统会报错。
代码
<filter>
<filter-name>opensession</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>mySessionFactory</param-value>
</init-param>
</filter>
<filter>
<filter-name>webwork</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>opensession</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
对于OpenSessionInView的配置中,singleSession应该设置为true,表示一个request只能打开一个 session,如果设置为false的话,session可以被打开多个,这时在update、delete的时候会出现打开多个session的异 常。
但是当设置为true的时候,系统的性能会因为用户的网络状况受到影响,当request在生成页面完成后,session才会被释放,所以如果用 户的网络状况比较差,那么连接池中的链接会迟迟不被回收,造成内存增加,系统性能受损。但是如果不用这种方法的话,lazy模式有体现不出它的优点,用? 不用?两难啊
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛session already closed Exception; Open Session In View提供了一种简便的方法,较好地解决了lazy loading问题.
它有两种配置方式OpenSessionInViewInterceptor和OpenSessionInViewFilter(具体参看SpringSide),功能相同,只是一个在web.xml配置,另一个在application.xml配置而已。
OpenSessionInView在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。
OpenSessionInViewInterceptor配置
<beans>
<bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean >4、让方法受Spring的事务控制(service和配置文件对应)