博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring 配置hibernate事务处理
阅读量:6684 次
发布时间:2019-06-25

本文共 9061 字,大约阅读时间需要 30 分钟。

hot3.png

1.HibernateTransactionManager功能介绍

 使用hibernate实现dml语句时,注意sessionFactory.opensession(),打开新的session它是没有事物的

  ② 如果为其配置了事务处理,要使用sessionFactory.getCurrentSession();如果不使用这个,那么将开启新的session,事务处理失效

  ③ 给一个类或者一个方法配置了@Transactional那么它的一系列子方法在使用getCurrentSession()都会使用同一个session,完成一整个事务处理的过程,如果不配置@Transactional,线程中没有session,使用getCurrentSession()爆出异常(ps:这种异常来源于hibernate的配置,hibernate.session.class=thread:没有session就开启一个,要有就使用当前的,我们这里面不涉及)

  ④ 无论是哪一种事务处理类,dataSourceManager还是HibernateTransactionManager,它们需要的数据源是不一样的,但是都是一样的使用方法

  ⑤ 如果用hibernate的访问数据,就用HibernateTransactionManager, 如果用jdbc,就用dataSourceManager

2.HibernateTemplate 事务处理

  ① 虽然hibernateTemplate所使用的方法是.save()、.update()但是在spring.xml的中同样要为其配置事务处理,原理是它需要的数据源是一个sessionFactory,而HibernateTransactionManager需要的数据源同样是sessionFactory,所以在Template的内部它所使用的同样是getCurrentSession().

3.源程序

  ① Model

package com.bjsxt.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="t_log")public class Log {	private int id;	private String msg;		@Id	@GeneratedValue	public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public String getMsg() {		return msg;	}	public void setMsg(String msg) {		this.msg = msg;	}		}
package com.bjsxt.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="user_U")public class User {	private int id;	private String name;		@Id	@GeneratedValue	public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	}

  ② Dao 接口

package com.bjsxt.dao;import com.bjsxt.model.Log;public interface LogDAO {	public void save(Log log);}
package com.bjsxt.dao;import com.bjsxt.model.User;public interface UserDAO {	public void save(User user);}

  ③ Dao 实现

package com.bjsxt.dao.impl;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.bjsxt.dao.LogDAO;import com.bjsxt.model.Log;@Component("logDAO") public class LogDAOImpl implements LogDAO {	private SessionFactory sessionFactory;	public SessionFactory getSessionFactory() {		return sessionFactory;	}		@Resource	public void setSessionFactory(SessionFactory sessionFactory) {		this.sessionFactory = sessionFactory;	}	public void save(Log log) {				Session s = sessionFactory.getCurrentSession();		s.save(log);		//throw new RuntimeException("error!");	}}
package com.bjsxt.dao.impl;import javax.annotation.Resource;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.junit.Test;import org.springframework.stereotype.Component;import org.springframework.transaction.annotation.Transactional;import com.bjsxt.dao.UserDAO;import com.bjsxt.model.User;@Component("u") public class UserDAOImpl implements UserDAO {	private SessionFactory sessionFactory;	public SessionFactory getSessionFactory() {		return sessionFactory;	}		@Resource	public void setSessionFactory(SessionFactory sessionFactory) {		this.sessionFactory = sessionFactory;	}	@Test    @Transactional(readOnly=true)	public void save(User user) {					Session s = sessionFactory.getCurrentSession();						s.save(user);					//throw new RuntimeException("exeption!");	}}

  ④ service(在这一层中加入@Transactional,有关联对象的dml时候,只要有一方出现异常,即事务回滚)

package com.bjsxt.service;import javax.annotation.Resource;import org.springframework.stereotype.Component;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.bjsxt.dao.LogDAO;import com.bjsxt.dao.UserDAO;import com.bjsxt.model.Log;import com.bjsxt.model.User;@Component("userService")public class UserService {		private UserDAO userDAO;	private LogDAO logDAO;		public void init() {		System.out.println("init");	}		public User getUser(int id) {		return null;	}		@Transactional(readOnly=true)	public void add(User user) {					userDAO.save(user);			Log log = new Log();			log.setMsg("a user saved!");			logDAO.save(log);//			int a = 0;//			int b = 1/a;			}	public UserDAO getUserDAO() {		return userDAO;	}		@Resource(name="u")	public void setUserDAO( UserDAO userDAO) {		this.userDAO = userDAO;	}			public LogDAO getLogDAO() {		return logDAO;	}		@Resource	public void setLogDAO(LogDAO logDAO) {		this.logDAO = logDAO;	}	public void destroy() {		System.out.println("destroy");	}}

  ⑤ Test

package com.bjsxt.service;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.bjsxt.model.User;//Dependency Injection//Inverse of Controlpublic class UserServiceTest {	@Test 	public void testAdd() throws Exception {		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");		UserService service = (UserService)ctx.getBean("userService");		System.out.println(service.getClass());		User user = new User();		user.setId(2);		user.setName("Jack");		service.add(user);		ctx.destroy();			}public static void main(String[] args) {	ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");	try {		new UserServiceTest().testAdd();	} catch (Exception e) {		// TODO Auto-generated catch block		e.printStackTrace();	}}}

  ⑥ HibernateTemplate 事务处理及测试程序

package com.bjsxt.hibernate.template;import javax.annotation.Resource;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.stereotype.Component;import org.springframework.transaction.annotation.Transactional;import com.bjsxt.dao.LogDAO;import com.bjsxt.dao.UserDAO;import com.bjsxt.model.User;@Component("h_template")public class HibernateTemplate {	private UserDAO userDAO;	private LogDAO logDAO;    private org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate;	public UserDAO getUserDAO() {		return userDAO;	}	public org.springframework.orm.hibernate3.HibernateTemplate getHibernateTemplate() {		return hibernateTemplate;	}	@Resource(type=org.springframework.orm.hibernate3.HibernateTemplate.class)	public void setHibernateTemplate(			org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate) {		this.hibernateTemplate = hibernateTemplate;	}	@Resource(name = "u")	public void setUserDAO(UserDAO userDAO) {		this.userDAO = userDAO;	}	public LogDAO getLogDAO() {		return logDAO;	}	@Resource	public void setLogDAO(LogDAO logDAO) {		this.logDAO = logDAO;	}	public void saveUser() {		User user = new User();		user.setName("Jack2");		this.hibernateTemplate.save(user);		int a = 0;		int b = 1/a;	}	public static void main(String[] args) {		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");	    HibernateTemplate template = (HibernateTemplate)ctx.getBean("h_template");	    template.saveUser();	}}

  ⑦ spring 配置

classpath:jdbc.properties
com.bjsxt.model.User
com.bjsxt.model.Log
update
org.hibernate.dialect.Oracle9Dialect
true

  ⑧ jdbc.properties

jdbc.driverClassName=oracle.jdbc.OracleDriverjdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcljdbc.username=newjdbc.password=sa

4. 项目列表

hibernate4 新特性

学习Spring+Hibernate,非常强大的框架,为了追新,就直接从最高版本开始学习了,这要冒很大的风险,因为网上可查到的资料大多是针对旧版本的,比如Spring3,Hibernate3。

根据我的测试,记录如下:

1.Spring4事务必须针对接口,否则报错。(之前可以不针对接口?)如果没有事务,则bean普通类也可以注入。

2.事务可以放在接口上,也可以放在实现上。

3.注意应用程序空间必须统一,否则事务失败。

4.Bean最好都交给Spring来管理,如果不是,则如果出现事务控制,可能因不同的应用空间而造成事务失败。

5.事务连接可以使用DataSourceTransactionManager,使用HibernateTransactionManager也可以。

复制代码
复制代码

 6.如果使用了JdbcTemplate和Hibernate,则应使用HibernateTransactionManager,如果使用DataSourceTransactionManager,则会提示没有活动Session错误。

(这个可能是我配置的有问题?)

7.如果使用事务,则调用时一定要使用接口,否则就会报告错误。

BillOperbaseBill=(BillOper)ctx.getBean("saleBill");

BillOper为第一没接口。

8.如果在程序中像这样使用:

sessionFactory.getCurrentSession().save(T);

如果不开启事务,则会报告

No Session found for current thread

错误。

9.Spring4+Hibernate4中不再支持HibernaterTemplate,只能使用原生的session接口来操作。

10.如果报告错误:hibernate:Cannot use identity column key generation with <union-subclass> mapping for ..... 

使用hibernate union-subclass 元素进行继承映射时会抛出此异常:Cannot use identity column key generation with <union-subclass> mapping for.............

原因是使用unnion-subclass 元素时 父类的标识属性生成器不能使用“indentity(native)”  可以选择"hilo”,"increment”等。

11.如果使用Spring+Hibernate,有时Hibernate的配置文件错误不容易发现(至少我没有找到好办法),可以直接使用Hibernate来调试。

12.有时在测试框架(junit)中无法显示Spring配置文件错误,可以在单独的程序单元中进行测试。

13.在需要用异常来控制事务的地方,不要捕获这个异常,或者再次抛出一个异常!

转载于:https://my.oschina.net/gaoguofan/blog/753440

你可能感兴趣的文章
关于重写session实现的时候可能会导至nginx 502的问题
查看>>
7z(p7zip)压缩软件在Linux下的安装和使用
查看>>
jetbrick-template 1.1.0 发布,支持 #tag, #macro, layout
查看>>
TCP的六个控制位
查看>>
进制转换
查看>>
我的友情链接
查看>>
新书上市:《FLUENT 14.0超级学习手册》
查看>>
mysql数据库query cache
查看>>
使用docker commit 来扩展一个image
查看>>
jsp 防止sql注入 之 preparestatement篇(转载)
查看>>
Linux之Ansible入门用法(实验解析)
查看>>
Linux系统如何在开机时修改root密码
查看>>
Anychat的绝对路径与相对路径
查看>>
我的友情链接
查看>>
如何使用网络库实现应用级消息收发
查看>>
Single Area OSPF
查看>>
rhel6之yum
查看>>
selenium+ant+testng测试框架简单介绍
查看>>
自己写的DBUtil数据库连接工具类
查看>>
登录多实例MySQL失败,修改密码临时解决,原因不明
查看>>