Spring4+Hibernate4 事务管理 配置 注解 AOP


在单独使用hibernate的时候

使用如下配置:

<property name="hibernate.current_session_context_class">thread</property>

根据文档,这个是hibernate3.1以后的一个新扩展,目的在于可以让我们在某一个上下文环境(比如说当前线程)中可以通过SessionFactory.getCurrentSession()得到同一个session会话. 
该方式hibernate会自动关闭session,但是事务控制仍然需要手动开始和提交。

public Long createUser(UserVO user) { Session session = sessionFactory.getCurrentSession(); Transaction tx = session.beginTransaction(); Long id = (Long) session.save(user); tx.commit(); return id; }

在Spring + Hibernate 整合时

我们希望通过 spring 使用声明式事务管理 或使用@Transactional注解进行事务管理。 
如果 hibernate.current_session_context_class 属性配置为thread话,会抛一个异常: get is not valid without active transaction。这个错误一般情况是因为由getCurrentSession得到的session中没有获得的transaction,我们一般要手动的调用Transaction tx = session.beginTransaction(); 和 tx.commit() 来控制事务。但是问题是,我们在spring的配置文件中不是已经通过aop,指定了此处由spring来管理事务吗,怎么还要手动处理事务?

解决办法是将 thread 改为 org.springframework.orm.hibernate4.SpringSessionContext。

<property name="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</property>

其实这就是默认值,把这段配置去掉,也是可以调用 sessionFactory.getCurrentSession(),以及使用 Spring 进行事务管理。

下面提我的配置和代码,经过测试ok。

pom.xml–项目jar包依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.taj.test</groupId> <artifactId>hibernate-test</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.11.Final</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!-- AOP --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <!-- AOP --> <!-- 测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!-- Oracle的驱动包 --> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> <version>10.2.0.4.0</version> </dependency> </dependencies> </project>

这里写图片描述

applicationContext.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <context:component-scan base-package="com.taj.**.dao" /> <context:component-scan base-package="com.taj.**.service" /> <!-- 数据源配置 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" /> <property name="username" value="ssh" /> <property name="password" value="ssh" /> </bean> <!-- session工厂 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> <property name="mappingDirectoryLocations"> <list> <value>classpath:com/taj/**/model</value> </list> </property> </bean> <!-- 事务管理器 --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 开启通过注解@Transactional管理事务 --> <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" /> <!-- 事务 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="query*" read-only="true" propagation="REQUIRED" /> <tx:method name="find*" read-only="true" propagation="REQUIRED" /> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <!-- 配置AOP --> <aop:config proxy-target-class="true"> <aop:pointcut expression="execution(* *..service..*Service*.*(..))" id="serviceMethod" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /> </aop:config> </beans>

 

hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="show_sql">true</property> <!-- <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.username">ssh</property> <property name="hibernate.connection.password">ssh</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:XE</property> --> <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> <!-- Hibernate的session管理:自动管理:"jta", "thread", and "managed". --> <!-- 默认为:org.springframework.orm.hibernate4.SpringSessionContext--> <!-- 默认时,除了手动管理,还可以交给Spring管理事务和关闭session(aop配置或注解实现) --> <!-- <property name="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</property> --> <!-- <mapping resource="com/taj/sshall/user/model/UserVO.hbm.xml"/> --> </session-factory> </hibernate-configuration>

userDao

package com.taj.sshall.user.dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.taj.sshall.user.model.UserVO; @Component(value="userDao") public class UserDaoSpringHibernateImpl extends UserDaoHibernateImpl { @Autowired @Override public void setSessionFactory(SessionFactory sessionFactory){ super.setSessionFactory(sessionFactory); } /** * sessionFactory.getCurrentSession() * 1. Hibernate 自动管理,thread方式实现。session自动关闭,但是需要手动开启和关闭事务。 * <property name="current_session_context_class">thread</property> * 2. Spring 自动管理,通过AOP或注解@Transactional实现。session和事务都自动管理。 * <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" /> */ @Override //@Transactional public Long createUser(UserVO user) { Session session = sessionFactory.getCurrentSession(); //Transaction tx = session.beginTransaction(); Long id = (Long) session.save(user); //tx.commit(); return id; } }

 

UserDaoHibernateImpl.Java

package com.taj.sshall.user.dao; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.criterion.Example; import com.taj.sshall.common.page.PageVO; import com.taj.sshall.user.model.UserVO; public class UserDaoHibernateImpl implements IUserDao { public SessionFactory sessionFactory; public List<UserVO> findUserPage(UserVO user, PageVO page) { //q_user_all Session session = sessionFactory.openSession(); //Query query = session.getNamedQuery("q_user_all"); Criteria criteria = session.createCriteria(UserVO.class); criteria.add(Example.create(user)); criteria.setFirstResult((page.getPage()-1) * page.getSize()); criteria.setMaxResults(page.getPage() * page.getSize()); @SuppressWarnings("unchecked") List<UserVO> list = criteria.list(); return list; } public List<UserVO> findUsersByName(String userName) { Session session = sessionFactory.openSession(); String hql = "from UserVO u where u.userName=?1"; Query query = session.createQuery(hql); query.setString("1", userName); @SuppressWarnings("unchecked") List<UserVO> list = query.list(); return list; } public UserVO findUserById(Long userId) { Session openSession = sessionFactory.openSession(); UserVO user = (UserVO)openSession.get(UserVO.class, userId); openSession.close(); return user; } public Long createUser(UserVO user) { Session openSession = sessionFactory.openSession(); Transaction tx = openSession.beginTransaction(); Long id = (Long) openSession.save(user); tx.commit(); openSession.close(); return id; } public void updateUser(UserVO user) { Session openSession = sessionFactory.openSession(); Transaction tx = openSession.beginTransaction(); openSession.update(user); tx.commit(); openSession.close(); } public void deleteUser(UserVO user) { Session openSession = sessionFactory.openSession(); Transaction tx = openSession.beginTransaction(); openSession.delete(user); tx.commit(); openSession.close(); } public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } } 

 

userService

package com.taj.sshall.user.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.taj.sshall.user.dao.IUserDao; import com.taj.sshall.user.model.UserVO; @Component("userService") public class UserServiceSpringImpl implements IUserService { @Autowired private IUserDao userDao; public Long createUser(UserVO user) { Long createUser = userDao.createUser(user); return createUser; } ----------- 省略其他方法 ----------- }

SSHUtils.java

package com.taj.sshall.common; import java.util.Arrays; import java.util.Properties; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SSHUtils { private static ThreadLocal<SessionFactory> sessionFactoryLocal; private static ThreadLocal<ApplicationContext> applicationContextLocal; public static SessionFactory getSessionFactory(){ if(sessionFactoryLocal == null){ Configuration cfg = new Configuration().configure(); Properties settings = cfg.getProperties(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(settings).build(); SessionFactory sf = cfg.buildSessionFactory(serviceRegistry); sessionFactoryLocal = new ThreadLocal<SessionFactory>(); sessionFactoryLocal.set(sf); } return sessionFactoryLocal.get(); } public static ApplicationContext getAppContext(){ if(applicationContextLocal == null){ ApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml"); applicationContextLocal = new ThreadLocal<ApplicationContext>(); applicationContextLocal.set(context); } return applicationContextLocal.get(); } public static void main(String[] args) { //测试sessionFactory SessionFactory sessionFactory = getSessionFactory(); Session openSession = sessionFactory.openSession(); System.out.println(openSession); openSession.close(); //测试appContext ApplicationContext appContext = getAppContext(); String[] names = appContext.getBeanDefinitionNames(); System.out.println(Arrays.toString(names)); } }

 

UserServiceSpringImplTest.java –(用Junit进行测试)

package com.taj.sshall.user.service; import static org.junit.Assert.*; import java.util.Date; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import com.taj.sshall.common.SSHUtils; import com.taj.sshall.user.model.UserVO; public class UserServiceSpringImplTest { private static IUserService userService; @BeforeClass public static void setUpBeforeClass() throws Exception { ApplicationContext appContext = SSHUtils.getAppContext(); userService = (IUserService) appContext.getBean("userService"); } @Test public void testCreateUser() { UserVO user = new UserVO(); user.setUserName("test_"); user.setPassword("1234567"); user.setAge(30); user.setEmail("test_@126.com"); user.setCreateDate(new Date()); user.setLastUpdateDate(new Date()); Long id = userService.createUser(user); assertTrue(id != null); } }

UserDaoHibernateImplTest.java –(用Junit进行测试)

package com.taj.sshall.user.dao; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Date; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.taj.sshall.common.SSHUtils; import com.taj.sshall.common.page.PageVO; import com.taj.sshall.user.model.UserVO; public class UserDaoHibernateImplTest { public IUserDao userDao; public SessionFactory sessionFactory; @Before public void before() throws Exception { UserDaoHibernateImpl dao = new UserDaoHibernateImpl(); dao.setSessionFactory(SSHUtils.getSessionFactory()); this.userDao = dao; this.sessionFactory = dao.getSessionFactory(); } @Test public void testFindUserPage() { UserVO user = new UserVO(); user.setEmail("test@126.com"); PageVO page = new PageVO(); for (int i = 1; i <= 5; i++) { page.setPage(i); List<UserVO> lst = userDao.findUserPage(user, page); System.out.println(Arrays.toString(lst.toArray())); System.out.println("----------------------------------------------\n"); } } @Test public void findUsersByName() { List<UserVO> users = userDao.findUsersByName("test_0"); for (UserVO userVO : users) { System.out.println("{" + userVO.getUserId() + ", " + userVO.getUserName() + ", " + userVO.getEmail() + "}"); } } @Test public void testFindUserById() { Long userId = 10000L; UserVO user = userDao.findUserById(userId); assertTrue("tajun77".equals(user.getUserName())); assertTrue("123456".equals(user.getPassword())); assertTrue("tajun77@126.com".equals(user.getEmail())); assertTrue(27 == user.getAge()); } @Test public void testCreateUser() { for (int i = 0; i < 25; i++) { UserVO user = new UserVO(); user.setUserName("test_"+i); user.setPassword("1234567"); user.setAge(30); user.setEmail("test@126.com"); user.setCreateDate(new Date()); user.setLastUpdateDate(new Date()); Long id = userDao.createUser(user); assertTrue(id != null); } } @Test public void testUpdateUser() { UserVO user = userDao.findUserById(10001L); int age = (user.getAge() + 7) % 30 + 20; user.setAge(age); userDao.updateUser(user); UserVO user2 = userDao.findUserById(10001L); assertTrue(user2.getAge() == age); } @Test public void testDeleteUser() { UserVO user = userDao.findUserById(10000L); user.setUserName("testDelete"); Long id = userDao.createUser(user); UserVO u_have = userDao.findUserById(id); assertTrue(u_have != null); UserVO udel = new UserVO(); udel.setUserId(id); userDao.deleteUser(udel);// userName=test id=10003 UserVO u_no = userDao.findUserById(id); assertTrue(u_no == null); } @After public void after() throws Exception { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery("delete from UserVO u where u.userId > 10122"); query.executeUpdate(); tx.commit(); session.close(); } }
 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM