Trong bài viết trước, mình đã giới thiệu với các bạn cách thể hiện Composite Primary Key trong JPA sử dụng annotation @Embeddable. Ngoài cách này ra, chúng ta còn có một cách để thể hiện Composite Primary Key trong JPA đó chính là sử dụng annotation @IdClass. Cụ thể như thế nào? Chúng ta hãy cùng nhau tìm hiểu trong bài viết này nhé các bạn.
Đầu tiên, mình cũng tạo một Maven project để làm ví dụ:
Mình sẽ sử dụng Hibernate làm implementation của JPA nên sẽ thêm Hibernate dependency như sau:
1 2 3 4 5 |
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.12.Final</version> </dependency> |
MySQL Connector:
1 2 3 4 5 |
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency> |
Project Lombok:
1 2 3 4 5 6 |
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope> </dependency> |
Table student:
1 2 3 4 5 6 |
CREATE TABLE `student` ( `id` int(11) NOT NULL, `code` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`, `code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
Để thể hiện Composite Primary Key của table student, đầu tiên chúng ta cũng tạo một class chứa thông tin của 2 cột primary key. Điểm khác biệt so với khi sử dụng annotation @Embeddable là chúng ta không cần sử dụng bất cứ annotation nào trong class này cả. Nội dung của class này như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.huongdanjava.jpaidclass; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import java.io.Serializable; @EqualsAndHashCode @Getter @Setter @AllArgsConstructor public class StudentId implements Serializable { private Integer id; private Integer code; } |
Các bạn lưu ý là đối tượng này cũng phải được implement interface Serializable và các phương thức equals() và hashCode() phải được khai báo nhé!
Tiếp theo là chúng ta sẽ khai báo entity Student sử dụng annotation @IdClass với đối tượng StudentId như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.huongdanjava.jpaidclass; import lombok.Getter; import lombok.Setter; import javax.persistence.*; @Entity @Table @Setter @Getter @IdClass(StudentId.class) public class Student { @Id private Integer id; @Id private Integer code; @Column private String name; } |
Như các bạn thấy, chúng ta sẽ khai báo annotation @IdClass với value là tên class chứa định nghĩa Composite Primary Key. Và một lưu ý nữa là trong khai báo entity Student, chúng ta phải khai báo thêm các cột Primary Key với annotation @Id các bạn nhé!
Vậy là xong rồi đó các bạn! Giờ mình sẽ làm một ví dụ để xem nó hoạt động như thế nào nhé.
Mình sẽ thêm tập tin cấu hình cho JPA, persistence.xml, nằm trong thư mục /src/main/resources/META-INF với nội dung như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<persistence version="2.1" 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_2_1.xsd"> <persistence-unit name="jpaexample" transaction-type="RESOURCE_LOCAL"> <class>com.huongdanjava.jpaidclass.Student</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpaexample" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="123456" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.use_sql_comments" value="true" /> </properties> </persistence-unit> </persistence> |
Tiếp theo, mình tạo mới một class ví dụ. Trong class này, mình sẽ sử dụng đối tượng EntityManager để tìm kiếm trong table student, những record có những cột primary key bằng những giá trị nào đó. Id lúc này sẽ là đối tượng StudentId.
Cụ thể như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com.huongdanjava.jpaidclass; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; public class Application { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaexample"); EntityManager em = emf.createEntityManager(); Student student = em.find(Student.class, new StudentId(1, 123)); System.out.println("Student name: " + student.getName()); em.close(); emf.close(); } } |
Nếu như trong database, mình đang có dữ liệu như sau:
thì khi chạy, kết quả sẽ như sau: