STACKJAVA

Spring Hibernate – Transaction trong Spring Hibernate. Code ví dụ Spring Hibernate Transaction.

Spring Hibernate – Transaction trong Spring Hibernate. Code ví dụ Spring Hibernate Transaction.

Ở phần trước chúng ta đã tìm hiểu về Spring ORM và code ví dụ với Spring Hibernate

Ở phần này chúng ta sẽ thực hiện quản lý trasaction của các truy vấn thông qua hibernate.

1. Transaction trong Spring Hibernate

(Xem lại Transaction là gì? Code ví dụ transaction với JDBC)

Để thực hiện quản lý hibernate bởi transactionManager ta khai báo trong file spring config:

<!-- Transaction config -->
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="transactionManager"
  class="org.springframework.orm.hibernate5.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>

Ở trong file DAO, để bật chức năng quản lý transaction ta dùng annotation: @Transactional(rollbackFor = Exception.class)

3. Code ví dụ

Ở ví dụ này mình sử dụng:

Tạo database:

CREATE SCHEMA `demo-spring-hibernate` ;
CREATE TABLE `demo-spring-hibernate`.`customer` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `address` VARCHAR(255) NULL,
  PRIMARY KEY (`id`));

Tạo maven project:

Thư viện sử dụng:

<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>stackjava.com</groupId>
  <artifactId>DemoJDBC</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
    <!-- Spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

    <!-- Hibernate -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.12.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>5.2.12.Final</version>
    </dependency>
    <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>1.4</version>
    </dependency>

    <!-- MySQL -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.45</version>
    </dependency>

  </dependencies>
</project>

File Spring config:

<?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:tx="http://www.springframework.org/schema/tx"
  xmlns:context="http://www.springframework.org/schema/context"
  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-4.3.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

  <context:annotation-config />
  <context:component-scan base-package="stackjava.com.springhibernate" />
  

  <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/demo-spring-hibernate" />
    <property name="username" value="root" />
    <property name="password" value="admin1234" />
  </bean>
  
  <!-- Transaction config -->
  <tx:annotation-driven transaction-manager="transactionManager" />
  
  <bean id="transactionManager"
    class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
  </bean>

  
  <bean id="sessionFactory"
    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="packagesToScan" value="stackjava.com.springhibernate.entities" />
    <property name="hibernateProperties" value="classpath:hibernate.properties" />
  </bean>

</beans>

 File Hibernate config:

hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hibernate.current_session_context_class=thread
hibernate.show_sql=true

File entity:

package stackjava.com.springhibernate.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "customer")
public class Customer {
  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @Column(name = "name")
  private String name;

  @Column(name = "address")
  private String address;

  public Customer() {
  }

  public Customer(int id, String name, String address) {
    this.id = id;
    this.name = name;
    this.address = address;
  }

  public Customer(String name, String address) {
    this.name = name;
    this.address = address;
  }

  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;
  }

  public String getAddress() {
    return address;
  }

  public void setAddress(String address) {
    this.address = address;
  }

}

File DAO:

package stackjava.com.springhibernate.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import stackjava.com.springhibernate.entities.Customer;

@Repository(value = "customerDAO")
@Transactional(rollbackFor = Exception.class)
public class CustomerDAO {
  
  @Autowired
  private SessionFactory sessionFactory;


  public void test(Customer customer) throws Exception {
    this.save(customer);
    this.demoException();
  }
  
  public void save(Customer customer) {
    Session session = this.sessionFactory.getCurrentSession();
    session.save(customer);
    System.out.println("save done!");
  }
  
  public void demoException() throws Exception {
    // do something
    throw new Exception("demo throw exception");
  }

}

Demo:

package stackjava.com.springhibernate.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import stackjava.com.springhibernate.dao.CustomerDAO;
import stackjava.com.springhibernate.entities.Customer;

public class MainApp {
  public static void main(String[] args) throws Exception {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    CustomerDAO customerDAO = (CustomerDAO) context.getBean("customerDAO");
    
    Customer customer = new Customer("Rooney", "Manchester");
    customerDAO.test(customer);
    context.close();
  }
}

Kết quả:

Hành động insert thành công nhưng sau đấy xảy ra lỗi nên dữ liệu sẽ bị rollback lại, không được save vào database nữa:

Spring Hibernate – Transaction trong Spring Hibernate. Code ví dụ Spring Hibernate Transaction.

Okay, Done!

Download code ví dụ trên tại đây.