Use Spring transaction to simplify Hibernate session management
Spring对Hibernate有很好的支持
DataSource ->SessionFactory-> HibernateTranscationManager
Hibernate中通过SessionFactory创建和维护Session。Spring对SessionFactory的配置进行了整合,无需再通过Hibernate.cfg.xml对SessionFactory进行设定。SessionFactory节点的mappingResources属性包含了映射文件的路径,list节点下可配置多个映射文件。hibernateProperties节点则容纳了所有的属性配置。可以对应传统的Hibernate.cfg.xml文件结构对这里的SessionFactory配置进行解读。
如果一个方法中既用了HibernateTemplate,又用了JdbcTemplate,应该怎么配单实例的db事务呢(多例免谈)用 DataSouceTransactionManager是不行的,而用HibernateTransactionManager就可以保证
原因的话看下它们源代码,会发现HibernateTransactionManager中的处理可以保证SessionFactoryUtil和datasourceutil都能在一个事务里取到同一个连接
所以如果使用hibernateTransactionManager的话,就完全可以保证SessionFactoryUtil和datasourceutil都能在一个事务里取到同一个连接!所有的疑问烟消云散了,
所以大家还是使用hibernateTransactionManager从而随心所欲的使用jdbctemplate和hibernatetemplate吧
下面是HibernateSessionFactory 和 HibernateTransactionManager的配置:
在applicationContext-hibernate.xml中:
1<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
2 <property name="dataSource"><ref bean="dataSource"/></property>
3 <property name="mappingResources">
4 <list>
5 <value>com/mycompany/model/User.hbm.xml</value>
6 ……………………………
7 </list>
8 </property>
9 <property name="hibernateProperties">
10 <props>
11 <prop key="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
12 <!--prop key="hibernate.show_sql">true</prop-->
13 <!--prop key="hibernate.hbm2ddl.auto">update</prop-->
14 </props>
15 </property>
16</bean>
Spring 提供了一个 HibernateTransactionManager,采用面向Hibernate的TransactionManager实现:org.springframework.orm.hibernate.HibernateTransactionManager。他用线程捆绑了一个Hibernate Session,用它来支持transactions。
1<bean id="transactionManager"
2 class="org.springframework.orm.hibernate.HibernateTransactionManager">
3 <property name="sessionFactory"><ref local="sessionFactory"/></property>
4 </bean>
sessionFactory Bean引用了HibernateSessionFactory,而transactionManager Bean引用了HibernateTransactionManage。 transactionManager Bean中有个sessionFactory属性。HibernateTransactionManager有个sessionFactory setter 和 getter方法,用来在Spring启动的时候实现“依赖注入” (dependency injection)的。 在sessionFactory 属性里引用sessionFactory Bean。这两个对象在Spring容器初始化后就被组装了起来了。
User使用一个TransactionProxyFactoryBean,它定义了一个setTransactionManager()。能很方便的处理申明的事物还有Service Object。TransactionProxyFactoryBean 还有个setter. 这会被Business service object(UserManager)引用, UserManager定义了业务层,并且它还有个属性,由setUserDAO()引用。
DataSource->SessionFactory->HibernateTemplate->HibernateDaoSupport
系统持久层中所有的类都继承自Spring提供的HibernateDaoSupport类,HibernateSupport实现了HibernateTemplate和SessionFactory实例的关联。HibernateTemplate对Hibernate Session操作进行了封装,提供了一个简单的方式实现了Hibernate-based DAO对象。借助HibernateTemplate我们可以脱离每次数据操作必须首先获得Session实例、启动事务、提交/回滚事务以及烦杂的try/catch/finally的繁琐操作。一个简单的Hibernate访问方法就完全解决了些麻烦! 无论是在多个DAO接口还是在多方事务的情况下,Spring使得多种DAO对象无缝地协同工作。
Spring为Hibernate的DAO提供工具类:HibernateDaoSupport。该类主要提供如下两个方法,方便DAO的实现:
public final HibernateTemplate getHibernateTemplate()
public final void setSessionFactory(SessionFactory sessionFactory)
其中,setSessionFactory方法用来接收Spring的ApplicationContext的依赖注入,可接收配置在Spring的SessionFactory实例,getHibernateTemplate方法则用来根据刚才的SessionFactory产生Session,最后生成HibernateTemplate来完成数据库访问。
对于简单的单步的动作,象find, load, saveOrUpdate或者delete的调用,HibernateTemplate提供更为便利的选择以代替象一行的回调的执行。此外HibernateDaoSupport类提供了setSessionFactory方法来接受一个SessionFactory,同时提供了getSessionFactory和getHibernateTemplate方法供其继承类使用。将这些结合起来,允许对于典型的需求给出了非常简单的DAO实现,如获得所有用户的方法:
public List getUsers(User user) {
return getHibernateTemplate().find("from User u order by upper(u.username)");
}
HibernateTemplate:public void saveUser(Person person){
4
5 getHibernateTemplate().saveOrUpdate(person);
6
7 }
采用事物配置,我们就不需要写那么多的try catch和finally了,因为容器会自动帮我们在执行方法前给我们加上。
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
也可以:
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
两种实现方式其实没有区别,尤其是第二种不要自己去关闭session,session在事务结束后都会自动关闭。 但是一定要注意延迟加载的问题,当对象在session关闭前没有从数据库中取得,而jsp中需要展示对象时,会提示LazyInitializationException,你可以通过OpenSessionInViewFilter来保证延迟加载不会出现错误,即:
<filter>
<filter-name>opensession</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>opensession</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
Use Spring transaction to simplify Hibernate session management的更多相关文章
- spring Transaction Management --官方
原文链接:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html 12. ...
- [原理][源代码解析]spring中@Transactional,Propagation.SUPPORTS,以及 Hibernate Session,以及jdbc Connection关系---转载
问题: 一. 1. Spring 如何处理propagation=Propagation.SUPPORTS? 2. Spring 何时生成HibernateSession ? 3. propagati ...
- [原理][来源解析]spring于@Transactional,Propagation.SUPPORTS,以及 Hibernate Session,以及jdbc Connection关联
Spring 捆绑Hibernate. 夹: 一. 1. Spring 怎样处理propagation=Propagation.SUPPORTS? 2. Spring 何时生成HibernateSe ...
- SSH项目过一段时间之后再访问会报一次Could not open Hibernate session for transaction 异常,Caused by: com.mysql.jdbc.CommunicationsException: Communications link failure due to underlyi,再重新方法即可访问成功(通常出现在过了一晚之后再去访问系统)
前端时间到客户那去进行项目的上线测试,将项目部署好之后,运行都是正常的,可是每到了第二天早上访问的时候,就会报一个Could not open Hibernate session for transa ...
- spring管理hibernate session的问题探究
我们再用spring管理hibernate的时候, 我们会继承HibernateDaoSupport 或者HibernateTemplate类. 我们不知道这两个类之间有什么关系. 也没有去关闭ses ...
- Hibernage错误:Could not open Hibernate Session for transaction
今天客户发来的错误,是SSH框架做的项目,是用户在登陆时候出现的错误,但刷新之后就没问题. 提示错误:Could not open Hibernate Session for transaction. ...
- Could not open Hibernate Session for transaction;
javax.servlet.ServletException: org.springframework.transaction.CannotCreateTransactionException: Co ...
- Hibernate Session & Transaction详解
Hibernate Session & Transaction详解 HIbernate中的Session Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持 ...
- org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Cannot open con
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session f ...
随机推荐
- spring logback 配置
<appender name="DubboInfo" class="ch.qos.logback.core.rolling.RollingFileAppender& ...
- Hibernate配置log4j日志环境
1.准备所需的jar 说明:具体所使用的jar包的版本与你所使用的Hibernate版本有关,我用的是(hibernate-release-4.3.11.Final) <1>准备slf4j ...
- 前端基础 JavaScript~~~ 数据处理 奇技淫巧!!!!!!
常用的JS数据处理手段 2016-09-21 17:40:07 1. number类型 数组中取出里面的最大/最小值: // 数组中取出 最小值 [数值] var n ...
- 【转】FPGA内部小数计算
FPGA内部计算小数 [转载] 谓定点小数,就是小数点的位置是固定的.我们是要用整数来表示定点小数,由于小数点的位置是固定的,所以就没有必要储存它(如果储存了小数点的位置,那就是浮点数了).既然没有 ...
- 使用 Fluent API 配置/映射属性和类型(摘自微软Data Access and Storage)
使用 Fluent API 配置/映射属性和类型 使用实体框架 Code First 时,默认行为是使用一组 EF 中内嵌的约定将 POCO 类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体 ...
- Android之Viewpager+Fragment实现懒加载
我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用.而ViewPager默认会缓存三页数据,即:Viewpager每加载一个Fra ...
- 使用snmp+mrtg监控CPU、流量、磁盘空间、内存
1.安装snmp rpm -qa|grep snmp* //查看是否安装了snmpyum -y install snmp* //安装snmp #vim /etc/snmp/snmpd.confroco ...
- C(C++)输入输出格式
c&c++输入输出控制格式 许多情况下,都需要控制输出结果的表现形式.如输出宽度.输出精度.输出格式等.C++的iomanip.h中定义了许多控制符,这些控制符可以直接插入到流中,控制数据的输 ...
- [Java] - Google API调用
由于Google已经完成被墙,要上Google必需使用代理或VPN. 这里使用的是Google的GoAgent代理做开发.(如何使用GoAgent,这里不写了,忽略500字.....) 本地测试的Go ...
- web前端响应式
一.响应式概述: 不仅仅是通过屏幕尺寸来动态改变页面容器的宽度等,完整的响应式网站的实现需要考虑到这些问题:响应式布局.响应式html和css.响应式媒体.响应式javascript. 二.移动端布局 ...