STACKJAVA

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`));

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>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 + "]";
  }

}

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

}

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ả:

Check lại database:

 

Okay, Done!

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

References:

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