Hibernate 允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Session 范围之内进行。如果 Service 层返回一个启用了延迟加载功能的领域对象给 Web 层,当 Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的 Hibernate Session 已经关闭,这些导致延迟加载数据的访问异常。而Spring为我们提供的OpenSessionInViewFilter过滤器为我们很好的解决了这个问 题。OpenSessionInViewFilter的主要功能是使每个请求过程绑定一个 Hibernate Session,即使最初的事务已经完成了,也可以在 Web 层进行延迟加载的操作。OpenSessionInViewFilter 过滤器将 Hibernate Session 绑定到请求线程中,它将自动被 Spring 的事务管理器探测到。

            看过OpenSessionInViewFilter以后就知道,OpenSessionInViewFilter的getSession方法中会对session的flushMode设定一个默认为NEVER的值。

我在用STRUCT2的时候只要在web.xml中配上下面的配置就可以了,不过我发现我在Spring MVC中这样配发现并没有起作用。


        openSessionInViewFilter
        org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
        
            flushMode
            AUTO
        

    

    
        openSessionInViewFilter
        /*
    

这时候解决办法有两个:
1:继承OpenSessionInViewFilter,并覆盖getSession,设施flushMode 为AUTO
2:通过spring的事务管理Hibernate的sessionFactory,对不同的数据操作作事务的隔离及限制

因为反正都要用到spring作事务管理,所以我在项目中采用了第二种方法,然后我在spring的配置文件中这样配

        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        
    


    
                    expression="execution(* com.pyp.workflow.dao.impl.*.*(..))" />
        
    


    
        
            
            
            
            
            
        

    

    然后配完之后并没有用,事务没有生产。这就挺奇怪了的,我搞了好久才查到

    大家先看下面配置,spring中自动扫包的

    <context:component-scan base-package="com">

            看过spring的参考手册的朋友都会这样配置,因为省事,一句话可以自动把com包低下的所有带annotation注解的类都实例化并配好了。所以习惯的也在springMVC中也作了这样的配置。

但如果这样简单的配置会导致刚才spring的事务配置失效原因:
        实例化@Controller类时,Spring会自动把关联的@Service(此@Service已做了@Transaction事务注解)类实例化,此时事务并未生效,导致@Transaction注解无效,事务未被注册,因此需要把@Controller和其它的@Service,@Components,@Reposity等分开实例化,在事务生效后,并且其它组件都实例化完成后,@Controller最后实例化。所以在SpringMVC的配置文件中

<context:component-scan base-package="com.*.*.*">

这个配置要配到Controller(对应struct2中的action)这一层的根目录下。这样就可以解决这个问题。


还有一种解决办法就是在spring中的配置文件中这样配

  

<context:component-scan base-package="com">   

   <context:exclude filter type="annotation" expression="org.springframework.stereotype.Controller"/>   

context:component-scan>


在spring mvc的配置文件这样配