`
footman265
  • 浏览: 118949 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

open session in view 研究

    博客分类:
  • SSH
阅读更多

在没有使用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配置而已。     
     Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。 
     OpenSessionInViewInterceptor配置 

Xml代码 
  1.     
  2. <beans>   
  3. <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">   
  4. <property name="sessionFactory">   
  5. <ref bean="sessionFactory"/>   
  6. </property>   
  7. </bean>   
  8. <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">   
  9. <property name="interceptors">   
  10. <list>   
  11. <ref bean="openSessionInViewInterceptor"/>   
  12. </list>   
  13. </property>   
  14. <property name="mappings">   
  15. ...   
  16. </property>   
  17. </bean> ... </beans>   


OpenSessionInViewFilter配置

Xml代码 
  1.    
  2. <web-app>   
  3. ...   
  4. <filter>   
  5. <filter-name>hibernateFilter</filter-name>   
  6. <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class>   
  7. <!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->   
  8. <init-param>   
  9. <param-name>singleSession</param-name>   
  10. <param-value>true</param-value>   
  11. </init-param>   
  12. </filter> ... <filter-mapping>   
  13. <filter-name>hibernateFilter</filter-name>   
  14. <url-pattern>*.do</url-pattern>   
  15. </filter-mapping> ... </web-app>   


    很多人在使用OpenSessionInView过程中提及一个错误: 
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition 
    看看OpenSessionInViewFilter里的几个方法

Java代码 
  1.     
  2.   
  3. protected void doFilterInternal(HttpServletRequest request,   
  4.         HttpServletResponse response,  
  5.         FilterChain filterChain) throws ServletException, IOException {   
  6.         SessionFactory sessionFactory = lookupSessionFactory();   
  7.         logger.debug("Opening Hibernate Session in OpenSessionInViewFilter");   
  8.         Session session = getSession(sessionFactory);   
  9.         TransactionSynchronizationManager.bindResource(    
  10.                 sessionFactory, new SessionHolder(session));   
  11.         try {    
  12.             filterChain.doFilter(request, response);   
  13.             }   
  14.         finally {   
  15.             TransactionSynchronizationManager.unbindResource(sessionFactory);   
  16.         logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");   
  17.         closeSession(session, sessionFactory);   
  18.         }  
  19. }   
  20. protected Session getSession(SessionFactory sessionFactory)  
  21.                    throws DataAccessResourceFailureException {   
  22.         Session session = SessionFactoryUtils.getSession(sessionFactory, true);   
  23.         session.setFlushMode(FlushMode.NEVER);   
  24.         return session;  
  25. }  
  26. protected void closeSession(Session session,   
  27.         SessionFactory sessionFactory)throws CleanupFailureDataAccessException {   
  28.     SessionFactoryUtils.closeSessionIfNecessary(session, sessionFactory);  
  29. }  


     关于绑定session的方式,通过看spring里TransactionSynchronizationManager的实现,发现:它维护一个 java.lang.ThreadLocal类型的resources,resources负责持有线程局部变量,这里resources持有的是一个 HashMap,通过TransactionSynchronizationManager.bindResource()方法在map里绑定和线程相关的所有变量到他们的标识上,包括如上所述的绑定在sessionFactory上的线程局部session。sessionHolder只不过是存放可以 hold一个session并可以和transtaction同步的容器。可以看到 OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。然后把该sessionFactory绑定到 TransactionSynchronizationManager,使request的整个过程都使用同一个session,在请求过后再接除该 sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。绑定以后,就可以防止每次不会新开一个Session呢?看看HibernateDaoSupport的情况:

Java代码 
  1.    
  2. public final void setSessionFactory(SessionFactory sessionFactory) {   
  3. this.hibernateTemplate = new HibernateTemplate(sessionFactory);   
  4. }    
  5. rotected final HibernateTemplate getHibernateTemplate() {  
  6. return hibernateTemplate;    
  7.            


     我们的DAO将使用这个template进行操作.

Java代码 
  1.      
  2. public abstract class BaseHibernateObjectDao   
  3.                 extends HibernateDaoSupportimplements BaseObjectDao {       
  4. protected BaseEntityObject getByClassId(final long id) {                  
  5. BaseEntityObject obj =(BaseEntityObject)getHibernateTemplate().execute(new HibernateCallback() {                          
  6. public Object doInHibernate(Session session)   
  7.          throws HibernateException{                                      
  8.  return session.get(getPersistentClass(),new Long(id));                  
  9.        }                  
  10.     }  
  11. );                  
  12. return obj;        
  13. }       
  14. public void save(BaseEntityObject entity) {                    
  15.        getHibernateTemplate().saveOrUpdate(entity);       
  16. }       
  17. public void remove(BaseEntityObject entity) {                
  18. try {                       
  19.        getHibernateTemplate().delete(entity);                
  20. catch (Exception e) {                        
  21.        throw new FlexEnterpriseDataAccessException(e);               
  22.        }        
  23. }         
  24. public void refresh(final BaseEntityObject entity) {                 
  25.        getHibernateTemplate().execute(new HibernateCallback(){                            
  26.             public Object doInHibernate(Session session)   
  27.            throws HibernateException   {                                  
  28.                  session.refresh(entity);                                        
  29.                  return color: #7f
    分享到:
    评论

相关推荐

    Open Session in View模式.PPT

    Open Session in View (OSIV) 模式是一种在基于Hibernate的Web应用程序中处理持久化数据的策略,它允许在视图层(例如JSP页面)中安全地访问延迟加载的对象,而无需担心Session已关闭的问题。以下是关于这个模式及其...

    struts2+hibernate3 open session in view

    在这个小项目中,"Open Session in View"(OSIV)模式被采用,这是一种处理持久化数据的策略,以避免在Web应用中出现常见的并发问题,如数据不一致和懒加载异常。 Struts2是一个强大的MVC框架,它提供了一种灵活的...

    Open_Session_In_View详解.doc

    ### Open_Session_In_View详解 #### 一、背景与概念 在使用Hibernate进行对象持久化时,经常遇到的一个问题是关于懒加载(lazy loading)的处理。懒加载是一种优化技术,允许在真正需要某个关联对象的数据时才加载...

    使用Spring引起的错误

    当使用Open Session In View模式时,如果Session的Flush Mode被设置为NEVER,并且尝试执行写操作(如更新或删除),就会触发“Write operations are not allowed in read-only mode (FlushMode.NEVER)”这个异常。...

    Hibernate Session释放模式

    3. **Open Session in View(OSIV)模式** OSIV模式旨在解决Web应用中,由于用户请求可能会引发多次数据库操作,而这些操作可能跨多个HTTP请求。在这种模式下,Session在整个HTTP请求周期内保持打开状态,直到请求...

    hibernate中session的管理

    3. **Open Session in View (OSIV)**:在视图渲染阶段保持Session打开,以允许最后时刻的懒加载,但需要注意防止Session泄露。 总的来说,Hibernate中Session的管理是保证多线程环境下数据一致性的重要环节。...

    spring中lazy=“true”的正常读取关联表(用opensessioninview)

    为了解决这个问题,Spring提供了一个过滤器 `OpenSessionInViewFilter` 或者 `OpenSessionInViewInterceptor`,通常简称为OSIV(Open Session In View)模式。 OSIV模式的核心思想是在Controller层和View层之间保持...

    Hibernate事务管理.

    在没有Spring提供的Open Session In View(OSIV)模式下,事务处理和懒加载(lazy loading)可能会遇到挑战。 懒加载是一种优化策略,允许关联对象在需要时才从数据库加载,而不是在初始加载实体时就全部加载。这...

    Struts Spring Hibernate 整合 OpenSessionInView 例子

    为了练手培训,给大家准备的 Open Session In View 的简单例子,纯代码,大家可以参考,其中主要说了六部分内容: 1.通过接口编程 2.通过spring注入dao到 action 3.通过 open session in view filter 支持 延迟加载...

    Spring延迟加载和声明式事务处理最终解决方案(修正版)

    1. **Open Session in View Interceptor (OSIV)**:这是Spring MVC中的一个拦截器,它的作用是在整个视图渲染过程中保持Hibernate Session的开放,确保在需要的时候可以进行延迟加载。配置OSIV拦截器后,如在`spring...

    ssh中getCurrentSession的使用

    - 首先,需要配置Hibernate,让其知道如何初始化SessionFactory,并启用Open Session In View模式。 - 在业务逻辑代码中,通过SessionFactory实例调用`getCurrentSession()`,然后执行数据库操作。 - 为了处理...

    集成spring的hibernate懒加载

    在Spring整合Hibernate的情况下,Session通常通过Transaction Management进行管理,比如使用`Open Session in View`(OSIV)模式或者基于注解的事务管理。 当你尝试在Controller层或者视图层访问懒加载的属性时,...

    open62541开发文档

    服务部分(Services)会介绍OPC UA的各种服务,如Secure Channel(安全通道服务集)、Session(会话服务集)、Discovery(发现服务集)、NodeManagement(节点管理服务集)、View(视图服务集)、Query(查询服务集...

    Android google io 2012 opensource已通过编译无错误

    View detailed session, code lab, and speaker information, including speaker bios, photos, and Google+ profiles +1 sessions right from the app Participate in public #io12 conversations on Google+ Guide...

    课程hibernate的事务和并发.pdf

    这种方式被称为ThreadLocal Session和Open Session in View模式,能够简化事务和Session的生命周期管理。 在实际应用中,需要确保正确地开启和结束Session及事务,并将其与数据访问操作结合。HibernateUtil类可以...

    UG Open API 二次开发

    - 在UG的界面环境(session)下运行。 - 程序被加载到UG的运行空间中(由UG分配的内存)。 - 特点包括执行代码小、连接速度快等。 - 入口函数通常是`ufusr`或`ufsta`。 - 示例代码结构如下: ```c #include...

    hello_xr_hpp:OpenXR“ hello_xr”示例的端口到OpenXR-Hpp绑定投影

    OpenXR的核心组件包括实例(Instance)、系统(System)、会话(Session)、视图配置(View Configuration)、交换图像(Swapchain)和动作(Action)。在C++中,这些都由对应的类表示,如`xr::Instance`, `xr::...

    ssh_inte2模板常用方法&延迟加载问题

    可以考虑将事务范围扩大,或者使用开放Session视图模式(Open Session In View,OSIV),让Session贯穿整个HTTP请求,但请注意,OSIV模式可能导致更多的并发问题,需要谨慎使用。 3. **使用Eager Loading**:如果...

    基于PHP的开源PHP博客平台OpenBlog源码.zip

    1. **MVC(Model-View-Controller)架构**:OpenBlog很可能采用了MVC模式来组织代码,这种设计模式将业务逻辑、数据和用户界面分离,使代码更易于维护和扩展。模型负责处理数据,视图用于显示结果,控制器则协调模型...

Global site tag (gtag.js) - Google Analytics