hibernate persist update 方法没有正常工作(不保存数据,不更新数据)
2016-04-15 19:21
537 查看
工程结构
问题描述
在工程中通过spring aop的方式配置事务,使用hibernate做持久化。在代码实现中使用hibernate persit()方法插入数据到数据库,使用hibernate update()方法更新数据。问题是执行这两个方法没有报错,但是也没有插入数据或者更新数据。原因
hibernate persist()以及update()方法只有事务执行flush()或者commit()方法,才将数据写入数据库。详细内容可以阅读博客:http://www.cnblogs.com/xiaoheike/p/5374613.html。使用spring aop配置的事务,在方法运行结束之后会运行commit()方法。程序实例可以看PersonDAOImpl.java(实现方法)小结,重点原因在于spring aop事务与session自己创建的事务是两个不同的事务,虽然最后spring aop 配置的事情 commit,但是session对象的事务并没有调用commit。以下是实例程序。事务配置(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: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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <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/Testdb" /> <property name="username" value="root" /> <property name="password" value="123456" /> </bean> <!-- Hibernate 4 SessionFactory Bean definition --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hiberante.format_sql">true</prop> </props> </property> <!-- hibernate配置文件放置位置,这个配置文件似乎也没有多大的作用了 --> <property name="configLocations"> <list> <value> classpath:/hibernate.cfg.xml </value> </list> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <tx:advice id="personServiceTxAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 表达式中的这些方法会执行如下的规则 --> <tx:method name="delete*" isolation="DEFAULT" read-only="false" propagation="REQUIRED" /> <tx:method name="update*" isolation="DEFAULT" read-only="false" propagation="REQUIRED" /> <tx:method name="save*" isolation="DEFAULT" read-only="false" propagation="REQUIRED" /> <tx:method name="*" isolation="DEFAULT" read-only="false" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="personServiceTxPointcut" expression="execution(* com.journaldev.dao.PersonDAO.*(..))" /> <aop:advisor id="personServiceTxAdvisor" advice-ref="personServiceTxAdvice" pointcut-ref="personServiceTxPointcut" /> </aop:config> <bean id="personDAO" class="com.journaldev.dao.PersonDAOImpl"> <property name="sessionFactory1" ref="sessionFactory" /> <property name="sessionFactory2" ref="sessionFactory" /> </bean> </beans>
PersonDAOImpl.java(实现方法)
package com.journaldev.dao; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import com.journaldev.model.Person; public class PersonDAOImpl implements PersonDAO { private SessionFactory sessionFactory1; private SessionFactory sessionFactory2; public void setSessionFactory1(SessionFactory sessionFactory1) { this.sessionFactory1 = sessionFactory1; } public void setSessionFactory2(SessionFactory sessionFactory2) { this.sessionFactory2 = sessionFactory2; } public void save1(Person person) { Session session1 = this.sessionFactory1.openSession(); session1.persist(person); session1.close(); } public void save2(Person person) { Session session1 = this.sessionFactory1.openSession(); Session session2 = sessionFactory2.openSession(); Transaction tx = session2.beginTransaction(); session1.persist(person); tx.commit(); session2.close(); session1.close(); } public void save3(Person person) { Session session1 = this.sessionFactory1.openSession(); Transaction tx = session1.beginTransaction(); session1.persist(person); tx.commit(); session1.close(); } @SuppressWarnings("unchecked") public List<Person> list() { Session session = this.sessionFactory1.openSession(); List<Person> personList = session.createQuery("from Person").list(); session.close(); return personList; } public Person findOne(Integer id) { Session session = this.sessionFactory1.openSession(); Person p = (Person) session.get(Person.class, id); session.close(); return p; } public void delete(Person person) { Session session = this.sessionFactory1.openSession(); session.delete(person); session.close(); } public void update1(Person person) { Session session = this.sessionFactory1.openSession(); session.update(person); session.close(); } public void update2(Person person) { Session session1 = this.sessionFactory1.openSession(); Session session2 = this.sessionFactory1.openSession(); Transaction tx = session2.beginTransaction(); session1.update(person); tx.commit(); session2.close(); session1.close(); } public void update3(Person person) { Session session1 = this.sessionFactory1.openSession(); Transaction tx = session1.beginTransaction(); session1.update(person); tx.commit(); session1.close(); } }
测试类
package com.journaldev.main; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.journaldev.dao.PersonDAO; import com.journaldev.model.Person; public class SpringHibernateMain { public static void main(String[] args) { test1(); test2(); test3(); } public static void test1() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); PersonDAO personDAO = context.getBean(PersonDAO.class); System.out.println("=================save1()=================="); // 增加一条数据 Person person = new Person(); person.setName("Pankaj"); person.setCountry("India"); personDAO.save1(person); System.out.println("================listAll()==================="); // 检索所有数据 List<Person> list = personDAO.list(); for (Person p : list) { System.out.println("所有记录:" + p); } System.out.println("================update1()==================="); // 更新一条Person记录 person.setCountry("zhongguo"); personDAO.update1(person); System.out.println("更新一条记录India-->zhongguo:" + personDAO.findOne(person.getId())); System.out.println("================delete()==================="); // 删除一条Person记录 personDAO.delete(person); context.close(); } public static void test2() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); PersonDAO personDAO = context.getBean(PersonDAO.class); System.out.println("=================save3()=================="); // 增加一条数据 Person person = new Person(); person.setName("Pankaj"); person.setCountry("India"); personDAO.save1(person); System.out.println("================listAll()==================="); // 检索所有数据 List<Person> list = personDAO.list(); for (Person p : list) { System.out.println("所有记录:" + p); } System.out.println("================update2()==================="); // 更新一条Person记录 person.setCountry("zhongguo"); personDAO.update1(person); System.out.println("更新一条记录India-->zhongguo:" + personDAO.findOne(person.getId())); System.out.println("================delete()==================="); // 删除一条Person记录 personDAO.delete(person); context.close(); } public static void test3() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); PersonDAO personDAO = context.getBean(PersonDAO.class); System.out.println("=================save3()=================="); // 增加一条数据 Person person = new Person(); person.setName("Pankaj"); person.setCountry("India"); personDAO.save3(person); System.out.println("================listAll()==================="); // 检索所有数据 List<Person> list = personDAO.list(); for (Person p : list) { System.out.println("所有记录:" + p); } System.out.println("================update3()==================="); // 更新一条Person记录 person.setCountry("zhongguo"); personDAO.update3(person); System.out.println("更新一条记录India-->zhongguo:" + personDAO.findOne(person.getId())); System.out.println("================delete()==================="); // 删除一条Person记录 personDAO.delete(person); context.close(); } }
运行结果
=================save1()================== ================update1()=================== Hibernate: select person0_.id as id1_0_0_, person0_.country as country2_0_0_, person0_.name as name3_0_0_ from PERSON person0_ where person0_.id=? 更新一条记录India-->zhongguo:null =================save2()================== ================update2()=================== Hibernate: select person0_.id as id1_0_0_, person0_.country as country2_0_0_, person0_.name as name3_0_0_ from PERSON person0_ where person0_.id=? 更新一条记录India-->zhongguo:null =================save3()================== Hibernate: insert into PERSON (country, name) values (?, ?) ================update3()=================== Hibernate: update PERSON set country=?, name=? where id=? Hibernate: select person0_.id as id1_0_0_, person0_.country as country2_0_0_, person0_.name as name3_0_0_ from PERSON person0_ where person0_.id=? 更新一条记录India-->zhongguo:id=8, name=Pankaj, country=zhongguo
原因分析
一共有三个测试例子,第一个例子test1()方法,调用save1()方法,使用spring aop配置的事务,从输出结果可以看出,数据没有插入数据库。update1()方法与save1()方法是相同情况。第二个例子test2()方法,调用save2()方法,persist()方法被包围在spring aop配置的事务和session2的事务中(事务有提交),从输出结果可以看出,数据没有插入数据库。update2()方法与save2()方法是相同情况。
第三个例子test3()方法,persist()方法被包围在spring aop配置的事务和session1的事务中(事务有提交),从输出结果可以看出,数据成功插入数据库。update3()方法与save3()方法是相同情况。
通过实例程序可以看出,persist(),以及update()方法需要在调用它们的session中的事务中执行,最后该session的事务需要commit。
源代码可以从github获取:https://github.com/xiaoheike/SpringHibernateWithTransactionExample,这份源代码是spring + hibernate + spring aop 配置事务的demo工程。在完成demo过程中发现该问题,一直无法理解,一周之后恍然大悟,遂写这篇博客。
教程结束,感谢阅读。
欢迎转载,但请注明本文链接,谢谢。
2016/4/15 18:38:01
相关文章推荐
- Android Launcher 启动简述 <2>
- MFC点击按钮跳出系统自带的文件选择框
- CodeForces 660F Bear and Bowling 4(斜率DP+二分)
- java并发:线程同步机制之计数器&Exechanger
- 如何用Swift实现一个好玩的弹性动画
- hdu 1102 Constructing Roads 最小生成树prim模板题
- Android--app启动 黑白屏问题 解决
- JAVA IO(一)
- redis 操作 hash 的测试
- 算法练习——ACM_1001_Exponentiation
- codeforces_333B_水过
- 1006. 换个格式输出整数 (15)
- 团队任务一详述
- Unity性能优化之Draw Call
- android实现自定义SwichButton
- 穷举法之水仙花数
- 相互观看与评价
- 面试题:android的安全机制有哪些
- 单链表(C++实现)
- qsort函数与sort函数