zoukankan      html  css  js  c++  java
  • 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(1);
            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>
  • 相关阅读:
    使用duilib链接错误 _declspec(dllimport)
    USB磁盘VID和PID 对应到次盘盘符相关文章
    路径拆分函数
    COM问题
    将对话框嵌入父窗体
    duilib的caption上的Edit无法激活
    LoadLibrary失败,GetLastError MOD_NOT_FOUND
    windows字符串
    windows界面库种类
    windows插件框架
  • 原文地址:https://www.cnblogs.com/sunfan1988/p/3495579.html
Copyright © 2011-2022 走看看