`
JavaCrazyer
  • 浏览: 3011755 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类

Hibernate温习(17)--OpenSessionInView模式

阅读更多

在WEB应用程序中,视图(JSP或Servlet)可能会通过导航从某个托管对象中拖出它的关联对象或集合数据,这些关联对象或集合数据如果是被延迟加载的(Hibernate本身就有几种默认延迟加载的情况,欲了解更多请看前面的文章),Hibernate就会抛出LazyInitializationException.因为没有持久化上下文存在时,是无法加载违背初始化的代理和集合的。

针对这个问题,Hibernate作者提出了OpenSessionInView模式作为解决方案,这个模式的主要思想是:

在用户的每一次请求过程始终保持一个持久化上下文打开着

OpenSessionInView模式的具体实现有以下三个步骤:

第一步:把Session绑定到当前线程上

要保证在一次请求中只有一个持久化上细纹,首先要把Session实例绑定到当前线程上,这需要在Hibernate的全局配置文件hibernate.cfg.xml中这样配置(其实就是前面关于Session文章的sf.getCurrentSession的一种配法)

 

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>

<!--把session附加到当前线程上-->
<property name="hibernate.current_session_context_class">thread</property>

</session-factory>
</hibernate-configuration>

 然后,在程序代码中获取Session实例时,使用SessionFactory的getCurrentSession()方法。这样,可以保证每一次请求的处理线程上只有一个持久化上下文实例的存在

第二步:用Filter过滤器在请求到达之前打开Session,在相应返回前关闭Session,代码如下

 

package com.javacrazyer.common;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
/*OSIV模式的Filter*/
public class OpenSessionInViewFilter implements Filter {
	  //这个之所以放在这里当成员变量因为它是线程安全的,严格的说,这个实例只能创建一次
    private SessionFactory sf;
  
	public void destroy() {
	
	}

	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
    Session sesion=null;
    try {
		//请求到达时,打开Session并启动事务
    	sesion=sf.getCurrentSession();
    	sesion.getTransaction().begin();
    	//执行请求处理链
    	arg2.doFilter(arg0, arg1);
    	//返回相应时,提交事务,关闭session
    	sesion.getTransaction().commit();
	} catch (Exception e) {
		//执行过程中,如果有异常,则必须回滚事务
		if (sesion.getTransaction().isActive()) {
		   sesion.getTransaction().rollback();
		}
	}
	}

	public void init(FilterConfig arg0) throws ServletException {
         sf=HibernateUtil.getSessionFactory();
	}

}

这段代码在请求处理完毕之后,也就是提交事务之后,并没有书写关闭session的代码,这是因为当前使用的是SessionFactory的getCurrentSession()来获取实例的,在当前线程上的事务被提交或回滚时,当前Session会自动清除和关闭的。所以无需手工关闭


  HibernateUtil如下

 

package com.javacrazyer.common;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

/**
 * Hibernate工具类
 * 
 */
public class HibernateUtil {
	private static final SessionFactory factory;
	
	private HibernateUtil(){}
	
	static{
		//加载Hibernate全局配置文件,根据配置信息创建SessionFactory工厂实例
		factory = new AnnotationConfiguration().configure().buildSessionFactory();
	}
	
	public static SessionFactory getSessionFactory(){
		return factory;
	}
	
	/**
	 * 本方法用来获取当前线程上绑定的Session实例
	 * 注意hibernate全局配置文件中,如果使用是JDBC事务,添加如下配置:<br/>
	 * <property name="hibernate.current_session_context_class">thread</property>
	 * @return
	 */
	public static Session getSession(){
		return factory.getCurrentSession();
	}
}

  第三步,在WEB应用的web.xml中配置Filter过滤器

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<!--OSIV的过滤器	-->
	<filter>
		<filter-name>osiv</filter-name>
		<filter-class>com.javacrazyer.common.OpenSessionInViewFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>osiv</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

 为了简单起见,本程序应用到了所有URL,在实际开发中,建议把它应用到执行期间需要操作数据库的URL上

分享到:
评论
1 楼 zdjray 2010-11-24  
标题写掉一个字母
btw:你的Spring系列怎么没有更新了?

相关推荐

    Spring hibernate opensessioninview

    ### Spring + Hibernate OpenSessionInView 模式的理解和应用 在Java Web开发中,Spring与Hibernate作为两个重要的框架,经常被一起使用来实现业务逻辑与数据持久化的处理。而在使用这两个框架时,为了更好地管理...

    Struts Spring Hibernate 整合 OpenSessionInView 例子

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

    SSH整合 struts+hibernate+spring

    **OpenSessionInView模式**是一种常用的Hibernate优化模式,其主要目的是解决Hibernate的一级缓存问题。通过这种方式,可以确保在一个HTTP请求的生命周期内,Hibernate的Session始终处于打开状态,从而避免了因...

    第30讲--Spring提供的CharacterEncoding和OpenSessionInView功能

    同时,需要注意的是,OpenSessionInView模式虽然方便,但也会带来潜在的问题,如事务边界不清晰和会话泄漏。因此,在实际应用中,应结合具体需求谨慎使用,并考虑使用更现代的解决方案,如Spring Data JPA的...

    hibernate面试题总结

    - **OpenSessionInView**:是一种设计模式,用于Web应用中,通过过滤器在请求开始时打开`Session`,结束时关闭,确保整个请求过程中`Session`可用,从而支持延迟加载。但这种方法可能导致过多的数据库连接,因此也...

    OpenSessionInView项目整合jar包

    在Java Web开发中,OpenSessionInView(OSIV)模式是一种常见的解决数据持久化问题的设计模式,主要用于Spring框架与Hibernate等ORM工具的集成。这个模式的主要目的是解决在HTTP请求处理过程中,由于Session范围内的...

    struts2+hibernate+spring

    -- Hibernate OpenSessionInView 过滤器 --&gt; &lt;filter-name&gt;hibernateFilter&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&lt;/filter-class&gt; &lt;!-- ...

    OA项目SSH整合框架

    一,集成 Spring 与 Hibernate 1,配置SessionFactory 1,配置 ---------------------- applicationContext.xml ------------------------ &lt;!-- 配置SessionFactory(整合Hibernate) --&gt; ...

    Struts+Spring+Hibernate开发实例.pdf

    - **OpenSessionInView** 是Hibernate的一个重要概念,它允许在视图层打开一个Session,这样就可以在渲染视图的时候访问数据库。 - **get() 和 set() 方法** 用于对象属性的获取和设置,在文档中被用于封装实体类...

    Struts+spring+hibernate面试资料

    - **OpenSessionInView模式**:这是一种解决懒加载异常的有效方案,通过确保Session在整个请求生命周期中保持打开状态,使得在任何时间点都可以获取到关联对象的数据。 ##### Hibernate的缓存机制 **缓存** 在...

    struts+spring+hibernate面试题.doc

    Hibernate的延迟加载与OpenSessionInView - **延迟加载**:在session范围内,仅在实际需要时加载关联对象的数据,提高性能。 - **OpenSessionInView**:在Web层通过Filter保持session的打开状态,直到请求结束,...

    struts+spring+hibernate面试题

    5. 延迟加载(Lazy Loading)和`openSessionInView`模式: - 延迟加载是在需要时才加载关联对象,确保只在session范围内加载,以提高性能。 - `openSessionInView`模式是在Web层使用Filter打开和关闭Session,确保...

    struts spring hibernate面试题

    Hibernate 的延迟加载与 openSessionInView - **延迟加载**:只在真正需要时才加载关联对象,以提高性能。 - **openSessionInView**:通过在 web 层设置一个 filter 来保持 session 打开状态,从而支持整个请求...

    HibernateSpring多数据库解决方案.doc

    5. 如果使用OpenSessionInView模式,需要确保读写操作的Session分配正确。 在实际应用中,还需要考虑事务管理和异常处理,确保系统稳定性和数据一致性。同时,根据业务需求,可能还需要动态切换数据源,这通常通过...

    收集的struts+spring+hibernate面试题.doc

    Hibernate 的延迟加载和 openSessionInView 模式 - **延迟加载**:只在真正需要时才加载关联对象,从而提高应用程序性能。 - **openSessionInView**:通过在 Web 层添加一个 Filter 来维持 Session 的打开状态,...

    SSH项目整合示例【OpenSessionInView】所用到的jar包

    OpenSessionInView(OSIV)模式是SSH整合中常见的一种优化策略,它在用户的一次HTTP请求过程中保持Hibernate Session,避免了多次打开和关闭Session,减少了N+1查询问题,提高了性能。 **Spring** 是一个全面的企业...

    SSH全注解环境搭建

    SSH框架是指Struts2、Spring、Hibernate这三种技术的组合,常被用于Java Web开发中。全注解配置相较于XML配置更加简洁,易于维护,因此在现代Web项目开发中越来越受到青睐。本文将详细介绍如何搭建一个基于全注解...

    韩顺平spring 雇员管理系统hibernate jar包

    在Spring框架中,通常使用SessionFactory的OpenSessionInView模式,确保每个HTTP请求都有一个独立的Session。 4. **DAO和Service层设计**:在雇员管理系统中,Hibernate常被用作DAO(Data Access Object)层的技术...

Global site tag (gtag.js) - Google Analytics