OpenSessionInView模式解决的问题:
  * hibernate事物边界问题

  * 因session关闭导致hibernate延迟加载例外的问题

事物边界:

    一个事物的完成应该是在业务层完成的,但是事物的创建却是在数据层来做,这样必定造成业务层和数据层耦合性增强。

延迟加载例外:

    
如你所知,延迟加载使用了动态代理机制,只有在真正使用这个对象的时候才会去访问数据库,但是如果在数据层进行了事物提交,session关闭,再去访问
数据就会导致延迟加载例外异常,所以我们必须加大session的生命周期,在访问数据之后关闭session。

因此我们可以通过OpenSessionInView模式来解决上面的问题

OpenSessionInView模式需要用到一个非常重要的一个类:ThreadLocal

OpenSessionInView模式:

  * 需要构建一个过滤器,把事物的创建及提交放在过滤器里进行。

  * 加大session的有效范围,把session放在当前线程里(ThreadLocal),使session在当前线程内有效,并且在当前线程内访问的是同一个session。

OpenSessionInView模式缺点:

  *并发性减弱

  *内存消耗加大

1.实体类:

  1. package com.yx.zzg.pojo;
  2. import java.util.Date;
  3. public class User {
  4. private String id;
  5. private String username;
  6. private String password;
  7. private Date createTime;
  8. private Date endTime;
  9. public String getId() {
  10. return id;
  11. }
  12. public void setId(String id) {
  13. this.id = id;
  14. }
  15. public String getUsername() {
  16. return username;
  17. }
  18. public void setUsername(String username) {
  19. this.username = username;
  20. }
  21. public String getPassword() {
  22. return password;
  23. }
  24. public void setPassword(String password) {
  25. this.password = password;
  26. }
  27. public Date getCreateTime() {
  28. return createTime;
  29. }
  30. public void setCreateTime(Date createTime) {
  31. this.createTime = createTime;
  32. }
  33. public Date getEndTime() {
  34. return endTime;
  35. }
  36. public void setEndTime(Date endTime) {
  37. this.endTime = endTime;
  38. }
  39. }

2.映射文件:

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.yx.zzg.pojo">
  6. <class name="User" table="t_user">
  7. <id name="id">
  8. <!-- 指定主键生成策略 -->
  9. <generator class="uuid" />
  10. </id>
  11. <property name="username" unique-key="true" />
  12. <property name="password" />
  13. <property name="createTime" />
  14. <property name="endTime" />
  15. </class>
  16. </hibernate-mapping>

3.提供一个过滤器:

  1. package com.yx.zzg.servelt;
  2. import java.io.IOException;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. import org.hibernate.Session;
  10. import org.hibernate.Transaction;
  11. import com.yx.zzg.util.HibernateUtil;
  12. public class OpenSessionInView implements Filter {
  13. public void destroy() {
  14. }
  15. public void doFilter(ServletRequest request, ServletResponse response,
  16. FilterChain filter) throws IOException, ServletException {
  17. Transaction tx = null;
  18. Session session = null;
  19. try {
  20. session = HibernateUtil.getThreadLocalSession();
  21. tx = session.beginTransaction();
  22. filter.doFilter(request, response);
  23. tx.commit();
  24. } catch (Exception e) {
  25. if (tx != null) {
  26. tx.rollback();
  27. throw new RuntimeException(e.getMessage(),e);
  28. }
  29. } finally {
  30. HibernateUtil.colseSession();
  31. }
  32. }
  33. public void init(FilterConfig arg0) throws ServletException {
  34. }
  35. }

4.web.xml中配置过滤器

  1. <filter>
  2. <filter-name>OpenSessionInView</filter-name>
  3. <filter-class>com.yx.zzg.servelt.OpenSessionInView</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>OpenSessionInView</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>

5.HibernateUtil类:

  1. package com.yx.zzg.util;
  2. import org.hibernate.Session;
  3. import org.hibernate.SessionFactory;
  4. import org.hibernate.cfg.Configuration;
  5. public class HibernateUtil {
  6. private static SessionFactory sessionFactory;
  7. //创建一个ThreadLocal对象
  8. private static ThreadLocal threadSession = new ThreadLocal();
  9. private HibernateUtil() {
  10. }
  11. static {
  12. Configuration cfg = new Configuration().configure();
  13. sessionFactory = cfg.buildSessionFactory();
  14. }
  15. /**
  16. * 从当前线程中获取session,如果没有,则得到session,并将此session放入当前线程中
  17. * @return
  18. */
  19. public static Session getThreadLocalSession() {
  20. Session session = (Session) threadSession.get();
  21. if (session == null) {
  22. session = getSession();
  23. threadSession.set(session);
  24. }
  25. return session;
  26. }
  27. /**
  28. * 关闭session,并将当前线程中的session设置为null
  29. */
  30. public static void colseSession() {
  31. Session session = (Session) threadSession.get();
  32. if (session != null) {
  33. session.close();
  34. threadSession.set(null);
  35. }
  36. }
  37. public static Session getSession() {
  38. return sessionFactory.openSession();
  39. }
  40. }

6.数据层方法:

  1. public User findUserById(String id) {
  2. User user = (User) HibernateUtil.getThreadLocalSession().load(
  3. User.class, id);
  4. return user;
  5. }

[转]OpenSessionInView模式的更多相关文章

  1. OpenSessionInView模式

    首先搭建建构 引入jar包 创建实体类  Emp.java public class Emp { private Integer empId;//员工ID private String empname ...

  2. SSH第一篇【整合SSH步骤、OpenSessionInView】

    前言 到目前为止,Struts2.Hibernate.Spring框架都过了一遍了.也写过了Spring怎么与Struts2整合,Spring与Hibernate整合-本博文主要讲解SSH的整合 整合 ...

  3. 【转】Hibernate 常见异常

    转载地址:http://smartan.iteye.com/blog/1542137 Hibernate 常见异常net.sf.hibernate.MappingException        当出 ...

  4. Struts2,Spring, Hibernate三大框架SSH的整合步骤

    整合步骤 创建web工程 引入相应的jar包 整合spring和hibernate框架 编写实体类pojo和hbm.xml文件 编写bean-base.xml文件 <!-- 1) 连接池实例 - ...

  5. hibernate中load和get方法的区别

    1.读取时机不同(当lazy=true的时候)    load是采用延迟机制(load语句不读库,等使用非主键时才去读库),而get不采用延  迟机制(get语句时马上读库): 2.搜索不到数据时的情 ...

  6. struts2支持的结果类型

    在struts2-core.jar/struts-default.xml中,我们可以找到关于result-type的一些配置信息,从中可以看出struts2组件默认为我们提供了这 些result-ty ...

  7. Spring 管理数据源

    Spring 管理数据源 不管通过何种持久化技术,都必须通过数据连接访问数据库,在Spring中,数据连接是通过数据源获得的.在以往的应用中,数据源一般是Web应用服务器提供的.在Spring中,你不 ...

  8. Hibernate 常见异常

    Hibernate 常见异常net.sf.hibernate.MappingException        当出现net.sf.hibernate.MappingException: Error r ...

  9. OpenSessionInViewFilter 的配置及替代方案(转)

    鸣谢:http://justsee.iteye.com/blog/1174999,http://blog.csdn.net/sunsea08/article/details/4545186 Sprin ...

随机推荐

  1. linux编程之文件操作

    在linux下用文件描述符来表示设备文件盒普通文件,文件描述符是一个整型的数据,所有对文件的操作都是通过文件描述符来实现的. 文件描述符是文件系统中连接用户空间和内核空间的枢纽,当我们打开一个或者创建 ...

  2. python并发模块之concurrent.futures(二)

    python并发模块之concurrent.futures(二) 上次我们简单的了解下,模块的一些基本方法和用法,这里我们进一步对concurrent.futures做一个了解和拓展.上次的内容点这. ...

  3. ajax之深入解析(2)

    我们前面实现了用原生的JavaScript代码实现ajax的异步数据传输.接下来,我们再使用一个流行的js框架jQuery来实现ajax. 通过 jQuery AJAX 方法,我们能够使用 HTTP ...

  4. CF868F Yet Another Minimization Problem

    题目描述: 给定一个序列,要把它分成k个子序列.每个子序列的费用是其中相同元素的对数.求所有子序列的费用之和的最小值. 输入格式:第一行输入n(序列长度)和k(需分子序列段数).下一行有n个数,序列的 ...

  5. Objective-C字符串处理的函数

    Objective-C字符串处理的函数 NSLog(@"字符串处理"); //获得字符串长度 NSString* str1=@"MAC OS Pro"; NSL ...

  6. linux命令(15):mount/umount命令

    使用挂盘之前可以先使用fdisk -l查看硬盘分区情况. 命令格式: mount [-t vfstype] [-o options] device dir -t vfstype 指定文件系统的类型.常 ...

  7. 《java并发编程实战》读书笔记3--对象的组合

    希望将一些现有的线程安全组件组合为更大规模的组件或程序 设计线程安全的类 如果对象中所有的域是基本类型变量,那么这些域将构成对象的全部状态.例如,LinkedList的状态就包括该链表中所有节点对象的 ...

  8. oracle11g如何创建数据库

    oracle11g创建数据库的步骤如下:1.按住键盘上Windows键,打开开始菜单,找到Database Configuration Assitant并打开:2.打开数据库配置助手Database ...

  9. hdu5735

    很美妙的一题 官方题解 http://www.cnblogs.com/duoxiao/p/5777632.html 感觉有meet in middle的思想 #include<bits/stdc ...

  10. Linux的文件帮助和运行级别

    man命令相关:man -1 +参数 表示查询第几章的帮助说明man -k +参数 表示以该参数为关键字查询所有相关命令或文件命令 --help 简单查询命令使用说明具体的帮助文档存储在/usr/sh ...