Code ví dụ Hibernate @EmbeddedId, @Embeddable, Id gồm nhiều column

Code ví dụ Hibernate @EmbeddedId, @Embeddable, Id gồm nhiều column.

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

Thông thường, khi tạo bảng, khóa chính thường sẽ là 1 column (có thể là kiểu text, int, tự tăng…). Tuy nhiên trong nhiều trường hợp ta cần sử dụng kết hợp nhiều column để làm khóa chính, Ví dụ bảng trung gian cho trường hợp ManyToMany thì người ta sẽ dùng luôn 2 khóa chính của 2 bảng để làm khóa chính cho bảng trung gian.

Trong ví dụ này mình sẽ hướng dẫn cách mapping từ Table sang Class Java cho trường hợp sử dụng nhiều column để làm khóa chính (primary key)

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

Tạo database MySQL

CREATE SCHEMA `hibernate-demo-3` ;

CREATE TABLE `hibernate-demo-3`.`employee` (
  `first_name` VARCHAR(45) NOT NULL,
  `last_name` VARCHAR(45) NOT NULL,
  `address` VARCHAR(255) NULL,
  PRIMARY KEY (`first_name`, `last_name`));

Ví dụ mình tạo table employee khóa chính xác định bởi 2 column là first_namelast_name tức là mỗi cặp này là duy nhất.

Cấu trúc Project

Code ví dụ Hibernate @EmbeddedId, @Embeddable, Id gồm nhiều column

Các 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>HibernateEnumDemo</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, kết nối tới MySQL

<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 Entity Manager</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-demo-3" />
      <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>

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)

File entity

package stackjava.com.hibernatedemo.entities;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;

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

  @EmbeddedId
  private Pk pk;

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

  // setter - getter

  @Embeddable
  public static class Pk implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Column(name = "first_name")
    private String firstName;

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

    public String getFirstName() {
      return firstName;
    }

    @Override
    public String toString() {
      return "Pk [firstName=" + firstName + ", lastName=" + lastName + "]";
    }

    // setter - getter
  }

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

}
  • Để định nghĩa id, primary key cho class ta sử tạo 1 class khác gồm các field tương ứng với các column sử dụng làm khóa chính sau đó sử dụng annotation @Embeddable để đánh dấu class này sử dụng là Id.
  • Thường class sử dụng làm Id chỉ dùng cho class gọi tới nó để làm Id nên mình sẽ để class này là inner class. Trong ví dụ này mình tạo inner class Pk để làm khóa. (Lưu ý, class Pk phải implements Serializable)
  • Khi khai báo Id cho trường hợp Id là 1 class khác ta dùng annotation @EmbeddedId thay vì annotation @Id

Demo Insert đối tượng với khóa chính nhiều hơn 1 field

package stackjava.com.hibernatedemo;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import stackjava.com.hibernatedemo.entities.Employee;

public class DemoInsert {

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

    Employee emp = new Employee();
    Employee.Pk pk = new Employee.Pk();
    pk.setFirstName("kai");
    pk.setLastName("tran");
    emp.setPk(pk);
    emp.setAddress("ha noi - viet nam");
    
    entityManager.persist(emp);
    entityManager.getTransaction().commit();

    System.out.println(emp);
    
    entityManager.close();
    entityManagerFactory.close();
  }

}

Ta tạo đối tượng Pk và set nó vào đối tượng Employee và persist như bình thường

Kết quả:

Hibernate: insert into employee (address, first_name, last_name) values (?, ?, ?)
Employee [pk=Pk [firstName=kai, lastName=tran], address=ha noi - viet nam]

Demo Insert đối tượng với khóa chính nhiều hơn 1 field

Demo select đối tượng với khóa chính nhiều hơn 1 field

package stackjava.com.hibernatedemo;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import stackjava.com.hibernatedemo.entities.Employee;

public class DemoSelect {

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

    Employee.Pk pk = new Employee.Pk();
    pk.setFirstName("kai");
    pk.setLastName("tran");
    
    Employee emp = entityManager.find(Employee.class, pk);
    System.out.println(emp);
    
    entityManager.close();
    entityManagerFactory.close();
  }

}

Kết quả:

Hibernate: select employee0_.first_name as first_na1_0_0_, employee0_.last_name as last_nam2_0_0_, employee0_.address as address3_0_0_ from employee employee0_ where employee0_.first_name=? and employee0_.last_name=?
Employee [pk=Pk [firstName=kai, lastName=tran], address=ha noi - viet nam]

 

Okay, Done!

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

 

References:

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

stackjava.com