Spring整合hibernate -声明事务管理
目录
1 sessionFactory 注入HibernateTransactionManager
2 XML配置的配置
3 添加annotation-driven
4 引入JAR包
5在service层添加事务声明的注释
6 改写数据库的实现类的方法,不再需要开始事务和提交事务,并且使用getCurrentSession
7 编写测试类通过
通过Spring的事务管理可以实现,对事务的统一管理,并且写节省冗余代码,结构清晰 抓到runtimeException进行回滚,
事务的策略Springl默认是required
1 sessionFactory注入org.springframework.orm.hibernate4.HibernateTransactionManager
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"></property>
</bean>
2 引入XML配置
1 xmlns:tx="http://www.springframework.org/schema/tx"
2 http://www.springframework.org/schema/tx
3 http://www.springframework.org/schema/tx/spring-tx.xsd
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">

3 添加annotation-driven
<tx:annotation-driven transaction-manager="txManager" />
4 引入JAR包
aopalliance-1.0
5在service层添加事务声明的注释
@Transactional
public void add(User user) {
userDao.save(user);
}
6 改写数据库的实现类的方法,不再需要开始事务和提交事务,并且使用getCurrentSession
public void save(User user) {
System.out.println(user.getName()+"-->"+user.getRemark()+" save --调用UserDaoImpl2!");
Session s = mySessionFactory.getCurrentSession();
s.save(user);
}
7 测试一下
@Test
public void testAdd() {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
UserServiceImpl.add(user);//调用方法
}
8 测试通过
下面会详细给出代码
9编译常见的报错信息
1 Add CGLIB to the class path or specify proxy interfaces.
引入 cglib-nodep-2.1_3.jar
2 org.hibernate.HibernateException: save is not valid without active transaction
去掉sessionFactory的property的配置 hibernate.current_session_context_class=thread
3 org.hibernate.MappingException: Unknown entity: com.entity.Log
sessionFactory里需要配置property的实体类
<property name="annotatedClasses">
<list>
<value>com.entity.User</value>
<value>com.entity.Log</value>
</list>
</property>
--------------------------------------------------------------------------------------------
Spring的事务管理具体的应用
例如 有一个服务service是完成以下功能
1 保存一个用户信息进A表,保存成功后打印一条日志进入B表
2 如果日志打印报错则插入的A表的用户回滚
完整的代码
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
"> <context:component-scan base-package="com.*"></context:component-scan>
<tx:annotation-driven transaction-manager="txManager" /> <bean id="mappings"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean> <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">-->
<!-- <property name="driverClassName" value="com.mysql.jdbc.Driver"/>-->
<!-- <property name="url" value="jdbc:mysql://localhost:3306/spring"/>-->
<!-- <property name="username" value="root"/>-->
<!-- <property name="password" value="root"/>-->
<!-- </bean>--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.entity.User</value>
<value>com.entity.Log</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
<!-- hibernate.current_session_context_class=thread-->
</value>
</property>
</bean> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"></property>
</bean> </beans>
service
package com.serviceImpl; import javax.annotation.Resource; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import com.dao.LogDao;
import com.dao.UserDao;
import com.entity.Log;
import com.entity.User;
@Component
public class UserServiceImpl { private UserDao userDao;
private LogDao logDao; @Transactional
public void add(User user) {
userDao.save(user);
Log log = new Log();
log.setContent(user.getName());
logDao.save(log);
} public void update(User user) {
userDao.update(user);
}
public void init() {// 初始方法
System.out.println("init");
}
public void destroy() {// 销毁方法
System.out.println("destory");
}
public UserDao getUserDao() {
return userDao;
} @Resource(name="userDaoImpl2")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} public LogDao getLogDao() {
return logDao;
}
@Resource
public void setLogDao(LogDao logDao) {
this.logDao = logDao;
}
}
UserDaoImpl2
package com.daoImpl; import javax.annotation.Resource; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import com.dao.UserDao;
import com.entity.User;
@Component
public class UserDaoImpl2 implements UserDao{
SessionFactory mySessionFactory; public void save(User user) {
System.out.println(user.getName()+"-->"+user.getRemark()+" save --调用UserDaoImpl2!");
Session s = mySessionFactory.getCurrentSession();
s.save(user);
} public void update(User user) {
System.out.println(user.getName()+"-->"+user.getRemark()+" update --调用UserDaoImpl2!");
Session s = mySessionFactory.getCurrentSession();
s.update(user);
} public SessionFactory getMySessionFactory() {
return mySessionFactory;
} @Resource
public void setMySessionFactory(SessionFactory mySessionFactory) {
this.mySessionFactory = mySessionFactory;
} }
logImpl
package com.daoImpl; import javax.annotation.Resource; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component; import com.dao.LogDao;
import com.entity.Log;
@Component
public class LogDaoImpl implements LogDao{
SessionFactory mySessionFactory; public void save(Log log) {
Session s = mySessionFactory.getCurrentSession();
s.save(log);
}
public SessionFactory getMySessionFactory() {
return mySessionFactory;
} @Resource
public void setMySessionFactory(SessionFactory mySessionFactory) {
this.mySessionFactory = mySessionFactory;
} }
logDao,userDao
package com.dao; import com.entity.Log;
import com.entity.User; public interface LogDao {
public void save(Log log);
}
package com.dao;
import com.entity.User;
public interface UserDao {
public void save(User user);
public void update(User user);
}
实体类
package com.entity; import javax.persistence.Entity;
import javax.persistence.Id; @Entity
public class User {
@Id
private int id;
private String name;
private String remark; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package com.entity; import javax.persistence.Entity;
import javax.persistence.Id; @Entity
public class Log {
@Id
private int id;
private String content; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
最后是测试类
package com.serviceImpl.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.entity.User;
import com.serviceImpl.UserServiceImpl; public class UserServiceImplTest {
User user; @Before
public void setUp() throws Exception {
user = new User();
user.setName("ttN");
user.setRemark("ttR");
} @Test
public void testAdd() {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
UserServiceImpl.add(user);//调用方法
}
}
执行结果
ttN-->ttR save --调用UserDaoImpl2!
Hibernate: insert into User (name, remark, id) values (?, ?, ?)
Hibernate: insert into Log (content, id) values (?, ?)

接下来测试一下,如果写入日志失败是否能够回滚
模拟 模拟日志的ID重复了,导致失败
@Transactional
public void add(User user) {
userDao.save(user);
Log log = new Log();
log.setId();
logDao.save(log);
}
测试类
@Before
public void setUp() throws Exception {
user = new User();
user.setName("testRollBack");
user.setRemark("testRollBack");
} @Test
public void testAdd() {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
UserServiceImpl.add(user);//调用方法
}
执行结果
testRollBack-->testRollBack save --调用UserDaoImpl2!
Hibernate: insert into User (name, remark, id) values (?, ?, ?)
Hibernate: insert into Log (content, id) values (?, ?)
报错信息
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null];
Caused by: java.sql.SQLException: Column 'content' cannot be null

存入的USER数据已经回滚
实体类其实还可以通过自动扫描的方式获取
<!-- <property name="annotatedClasses">-->
<property name="packagesToScan">
<list>
<value>com.entity</value>
<!-- 这些都不需要一个一个写了 <value>com.entity.User</value>-->
<!-- <value>com.entity.Log</value>-->
</list>
</property>
Spring整合hibernate -声明事务管理的更多相关文章
- Spring整合hibernate4:事务管理
Spring整合hibernate4:事务管理 Spring和Hibernate整合后,通过Hibernate API进行数据库操作时发现每次都要opensession,close,beginTran ...
- Spring整合hibernate4:事务管理[转]
Spring和Hibernate整合后,通过Hibernate API进行数据库操作时发现每次都要opensession,close,beginTransaction,commit,这些都是重复的工作 ...
- Spring+SpringMVC+Hibernate小案例(实现Spring对Hibernate的事务管理)
原文地址:https://blog.csdn.net/jiegegeaa1/article/details/81975286 一.工作环境 编辑器用的是MyEclipse,用Mysql数据库,mave ...
- Spring整合Hibernate--声明式事务管理
Spring指定datasource 1. 新建jdbc.properties文件: jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc: ...
- 【Java EE 学习 53】【Spring学习第五天】【Spring整合Hibernate】【Spring整合Hibernate、Struts2】【问题:整合hibernate之后事务不能回滚】
一.Spring整合Hibernate 1.如果一个DAO 类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了:如果一个DAO类没有 ...
- spring整合hibernate
spring整合hibernate包括三部分:hibernate的配置.hibernate核心对象交给spring管理.事务由AOP控制 好处: 由java代码进行配置,摆脱硬编码,连接数据库等信息更 ...
- 使用Spring整合Hibernate,并实现对数据表的增、删、改、查的功能
1.1 问题 使用Spring整合Hibernate,并实现资费表的增.删.改.查. 1.2 方案 Spring整合Hibernate的步骤: 1.3 步骤 实现此案例需要按照如下步骤进行. 采用的环 ...
- spring整合hibernate时报错:org.hibernte.engine.transaction.spi.transactioncontext
错误提示:Caused by:java.lang.ClassNotFoundException: org.hibernte.engine.transaction.spi.transactioncont ...
- Maven环境下搭建SSH框架之Spring整合Hibernate
© 版权声明:本文为博主原创文章,转载请注明出处 1.搭建环境 Spring:4.3.8.RELEASE Hibernate:5.1.7.Final MySQL:5.7.17 注意:其他版本在某些特性 ...
随机推荐
- 一次对真实网站的SQL注入———SQLmap使用
网上有许多手工注入SQL的例子和语句,非常值得我们学习,手工注入能让我们更加理解网站和数据库的关系,也能明白为什么利用注入语句能发现网站漏洞. 因为我是新手,注入语句还不太熟悉,我这次是手注发现的注点 ...
- apply()技巧
apply技巧: 可以将数组的每一项分别作为参数传入函数. var value = [3,6,34,90]; alert(Math.max.apply(Math,value)); 这个技巧的关 ...
- Using Autorelease Pool Blocks
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAut ...
- tableViewcell上放定时器
tableviewcell上的定时器: 1.创建一个管理定时器的TimerManger类, TimerManger.h #import <Foundation/Foundation.h> ...
- 查看数据库表存储引擎MyISAM/InnoDB
Mysql: show table status *MyISAM不支持PDO的事务
- VC-基础-WebBrowser控件中弹出新网页窗口
用webbrowser控件浏览网页时,常弹出新的网页窗口,若不做任何控制的话,会在默认浏览器(一般是IE)中打开,这样就在新的窗口打开了,原程序就很难控制了,且存在webbrowser控件和IE的se ...
- javaweb基础(29)_EL表达式
一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...
- API调用微信getWXACodeUnlimit()获取小程序码
微信文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html? ...
- 基于Qt Creator实现中国象棋人机对战, c++实现
GitHub地址: https://github.com/daleyzou/wobuku 这是自己大一学完c++后,在课程实践中写过的一个程序,实现象棋人机对战的算法还是有点难的, 自己当时差不多也是 ...
- The Apache Tomcat Servlet/JSP Container
1.Tomcat部署的场景分析 通常,我们对tomcat单机部署需求可以分为几种: 单实例单应用 (一个tomcat 一个web应用) 单实例多应用 (一个tomcat多个应用) 多实例单应用 (多个 ...