工程结构

问题描述

在工程中通过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

hibernate persist update 方法没有正常工作(不保存数据,不更新数据)的更多相关文章

  1. hibernate的update() 更新延迟或者无法更新,导致同个service调用存储过程执行方法不精确

    hibernate的update()方法无法更新,不报错 原因是hibernate的update方法操作的是缓存,可以flush下先. 设置缓存为false理论上也可. 在一个serivce方法里,执 ...

  2. Hibernate的注解方法的使用

    1.配置映射关系的xml方式 我们知道,Hibernate是一个典型的ORM框架,用以解决对象和关系的不匹配.其思想就是将关系数据库中表的记录映射成为对象,以对象形式展现,这样一来,就可以把对数据库的 ...

  3. [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. Hibernate各保存方法之间的差 (save,persist,update,saveOrUpdte,merge,flush,lock)等一下

    hibernate保存  hibernate要保存的目的是提供一个方法,多.它们之间有许多不同之处,点击此处详细说明.使得差: 一.预赛: 在所有.阐释.供hibernate,,transient.p ...

  5. hibernate的各种保存方式的区别 (save,persist,update,saveOrUpdte,merge,flush,lock)等

    hibernate的保存hibernate对于对象的保存提供了太多的方法,他们之间有很多不同,这里细说一下,以便区别:一.预备知识:在所有之前,说明一下,对于hibernate,它的对象有三种状态,t ...

  6. hibernate的各种保存方式的区别 (save,persist,update,saveOrUpdte,merge,flush,lock)

    hibernate的保存hibernate对于对象的保存提供了太多的方法,他们之间有很多不同,这里细说一下,以便区别:一.预备知识:在所有之前,说明一下,对于hibernate,它的对象有三种状态,t ...

  7. hibernate中保存一个对象后再设置此对象的属性为什么不需要调用update方法了

    hibernate中保存一个对象后再设置此对象的属性为什么不需要调用update方法了 例如session.save(user);user.setAge(20); 原因: hibernate对象的三种 ...

  8. Hibernate HQL的update方法详解

    虽然hibernate提供了许多方法对数据库进行更新,但是这的确不能满足开发需要.现在讲解一下用hql语句对数据进行更新. 不使用参数绑定格式String hql="update User ...

  9. Hibernate的hql语句save,update方法不执行

    Hibernate的hql语句save,update方法不执行 可能出现的原因问题: 未进行事务管理 需要进行xml事务配置或者注解方式的事务配置

随机推荐

  1. [css]水平垂直居中的方法

    1.top:cale(50% - 2rem); left:cale(50% - 2rem);

  2. AJAX格式

    var xmlHttp;function getXmlHttp(){ if(window.ActiveXObject){ xmlHttp = new ActiveXObject("MICRO ...

  3. 通过淘宝IP地址库获取IP位置

    地址:http://ip.taobao.com/ 提供的服务包括: 1. 根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家.省.市和运营商. 2. 用户可以根据自己 ...

  4. spring IOC装配Bean(注解方式)

    1 Spring的注解装配Bean (1) Spring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean (2) Spring的框架中提供了与@Componen ...

  5. eclipse + python dev

    错误:Project interpreter not specified解决方法 http://blog.csdn.net/magictong/article/details/7288732 安装Py ...

  6. It will affect staff as well.

    Premier Foods has reduced its number of suppliers dramatically in the last 12 months. In 2013 it mad ...

  7. web.config 配置

    一.认识Web.config文件   Web.config 文件是一个xml文本文件,它用来储存 asp.NET Web 应用程序的配置信息(如最常用的设置asp.NET Web 应用程序的身份验证方 ...

  8. 获取 view所在的VC

    - (UIViewController*)viewController { for (UIView* next = [self superview]; next; next = next.superv ...

  9. restful

    根据名称对应 相当于换了别名(很无聊)

  10. GeoHash原理解析

    GeoHash 核心原理解析       引子 一提到索引,大家脑子里马上浮现出B树索引,因为大量的数据库(如MySQL.oracle.PostgreSQL等)都在使用B树.B树索引本质上是对索引字段 ...