Code ví dụ Hibernate tự sinh ID dạng text, String

Code ví dụ Hibernate tự sinh ID dạng text, String

(Xem thêm: Hướng dẫn tự học Hibernate)

(Xem thêm: Code ví dụ Hibernate ID tự tăng (@GeneratedValue, @GenericGenerator))

Ở bài trước mình đã thực hiện ví dụ tạo id tự tăng (tự động tạo id) dạng số (Long, Integer). Nhưng với trường hợp id không phải dạng số thì làm thế nào? Ví dụ chúng ta hay bắt gặp id có dạng: EMP001, VNE002, 0001… và nhưng id này cũng tự tăng nhé.

Trong bài này mình sẽ làm code ví dụ thực hiện điều đó.

Các công nghệ sử dụng

Tạo database

Mình tạo 1 database với table employee trong đó column id là primary key dạng text.

CREATE SCHEMA `hibernate-generate-id` ;

CREATE TABLE `hibernate-generate-id`.`employee` (
  `id` VARCHAR(45) NOT NULL,
  `name` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));

Code ví dụ Hibernate tự sinh ID dạng text

Tạo Maven Project

Code ví dụ Hibernate tự sinh ID dạng text, String

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>HibernateGenCustomId</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <hibernate.version>5.3.6.Final</hibernate.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>${hibernate.version}</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>${hibernate.version}</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.46</version>
    </dependency>
  </dependencies>
</project>

File cấu hình hibernate – jpa

Chứa thông tin kết nối tới database (url, username, password), liệt kê các entity class được mapping với các table trong database.

Trong ví dụ này mình sử dụng entityManager nên sẽ khai báo file persistence.xml nếu các bạn sử dụng hibernateSession thì có thể khai báo file hibernate.cfg.xml

(Xem lại: Code ví dụ Hibernate EntityManager, EntityManagerFactory)

(Xem lại: Code ví dụ Hibernate Session, SessionFactory)

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
  version="2.1">
  <persistence-unit name="persistence">
    <description>Demo Hibernate Generate Custom ID</description>
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hibernate-generate-id" />
      <property name="javax.persistence.jdbc.user" value="root" />
      <property name="javax.persistence.jdbc.password" value="admin1234" />
      <property name="hibernate.show_sql" value="true" />
    </properties>
  </persistence-unit>
</persistence>

File entity

package stackjava.com.hibernatedemo.entities;

import javax.persistence.I;
import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "employee")
public class Employee {

  @Id
  @GeneratedValue(generator = "my_generator")  
  @GenericGenerator(name = "my_generator", strategy = "stackjava.com.hibernatedemo.generator.MyGenerator")
  @Column(name="id")
  private String id;

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

  // getter - setter - constructor

  @Override
  public String toString() {
    return "Employee [id=" + id + ", name=" + name + "]";
  }

}
  • @GeneratedValue(generator = “my_generator”): khai báo phương thức sinh id, ở đây khai báo sử dụng generator có tên là my_generator
  • @GenericGenerator(name = “my_generator”, strategy = “stackjava.com.hibernatedemo.generator.MyGenerator”): khai báo generator có tên là my_generator được định nghĩa ở class stackjava.com.hibernatedemo.generator.MyGenerator

Class định nghĩa cách sinh id

package stackjava.com.hibernatedemo.generator;

import java.io.Serializable;
import java.util.stream.Stream;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;

public class MyGenerator implements IdentifierGenerator {

  private String prefix = "EMP";
  @Override
  public Serializable generate(SharedSessionContractImplementor session, Object obj) throws HibernateException {
    String query = "SELECT e.id FROM Employee e";
    Stream<String> ids = session.createQuery(query, String.class).stream();

    Long max = ids.map(o -> o.replace(prefix, "")).mapToLong(Long::parseLong).max().orElse(0L);

    return prefix + (String.format("%04d", max + 1));
  }

}
  • IdentifierGenerator  là interface định nghĩa Generator cho hibernate
  • Ở đây mình sẽ sinh id có dạng EMP0000 sau đó tăng dần từng đơn vị EMP0001, EMP0002… (3 ký tự đầu tiên luôn là EMP, 4 ký tự đằng sau dạng số và tăng dần).

Mình sẽ select tất cả các id có trong table employee, tách lấy 4 số đằng sau và lấy số lớn nhất. ID được tạo ra sẽ là EMP + số lớn nhất + 1 đơn vị.

(Thay vì select từ database các bạn có thể tạo thuật toán để sinh số ngẫu nhiên ko bị trùng, hoặc lưu giá trị lớn nhất vào bộ nhớ đệm, mỗi lần tạo id sẽ lấy từ bộ nhớ đệm chứ không cần phải query từ database nữa)

Demo

package stackjava.com.hibernatedemo;

import javax.persistence.*;

import stackjava.com.hibernatedemo.entities.Employee;

public class Demo {

  public static void main(String[] args) {
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence");
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    entityManager.getTransaction().begin();

    Employee emp1 = new Employee("kai");
    Employee emp2 = new Employee("sena");
    entityManager.persist(emp1);
    entityManager.persist(emp2);

    entityManager.getTransaction().commit();
    System.out.println(emp1);
    System.out.println(emp2);
    entityManager.close();
    entityManagerFactory.close();
  }

}

Kết quả:

Code ví dụ Hibernate tự sinh ID dạng text, String

Check lại database:

Code ví dụ Hibernate tự sinh ID dạng text, String

 

Okay, Done!

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

References:

https://docs.jboss.org/…/GenericGenerator.html

stackjava.com