Written by : Nguyễn Hòa Khiêm
Email : khiem31200@gmail.com
Phone : 0936439200
Bài viết được dịch từ : JPA @Embedded và @Embeddable của Bealdung

1. Tổng quát :

Trong bài viết này ta sẽ biết cách làm thế nào để ánh xạ một thực thể có chứa các thuộc tính nhúng vào một bảng cơ sở dữ liệu duy nhất.
Chúng ta sẽ dùng hai annotation @Embeddable@Embedded được cung cấp bởi Java Persistence API (JPA) để thực hiện.

2. Định nghĩa Entity

Đầu tiên, ta xác định một lớp được gọi là Company
Lớp Company sẽ lưu trữ các thông tin cơ bản như tên công ty, địa chỉ, điện thoại cũng như thông tin của người liên hệ như code dưới đây.

public class Company {
    private Integer id;
    private String name;
    private String address;
    private String phone;
    private String contactFirstName;
    private String contactLastName;
    private String contactPhone;
    // standard getters, setters
}

Ta vừa tạo ra bảng công ty, công ty có rồi tiếp theo ta phải có tiếp người liên hệ.
Tuy nhiên, có vẻ như nó nên được tạo ra ở một lớp riêng biệt. Vấn đề là chúng ta không muốn tạo một bảng riêng cho những chi tiết đó => Hay xem @Embedded@Embeddable có thể làm được

3. @Embeddable

JPA cung cấp annotation @Embeddable để khai báo rằng một lớp sẽ được nhúng bởi các entity(Thực thể) khác.
Ta tạo ra một class có tên là ContactPerson và đánh annotation @Embeddable cho nó và nó sẽ được nhúng vào các entity khác

@Embeddable
public class ContactPerson {

    private String firstName;

    private String lastName;

    private String phone;

    // standard getters, setters
}

4. @Embedded

Annotation @Embedded được sử dụng để khai báo rằng nhúng thực thể được đánh dấu @Embeddable ở phía trên vào thực thể ở dưới đây.
Cụ thể như sau: Ta sẽ sửa đổi lớp thực thể Company . Ta sẽ thêm annotation @Embedded để nhúng ContactPerson thay vì các trường riêng biệt.

@Entity
public class Company {
    @Id   @GeneratedValue   private Integer id;
    private String name;
    private String address;
    private String phone;
    @Embedded  private ContactPerson contactPerson;

    // standard getters, setters
}

Kết quả là ta có thực thể Company, nhúng chi tiết người liên hệ và ánh xạ tới một bảng cơ sở dữ liệu duy nhất.

5. Ghi đè thuộc tính

Vấn đề là các trường của ta được gọi là những thứ như contactFirstName trong lớp Company ban đầu của ta và bây giờ là firstName trong lớp ContactPerson của chúng tôi . Vì vậy, JPA sẽ muốn ánh xạ những thứ này thành contact_first_name và first_name, tương ứng.

Tuy nhiên như hai lớp ở trên ta đều có cột điện thoại phone vì vậy ghi đè lên nó sẽ trùng lặp

Giải pháp ở đây là ta sử dụng @AttributeOverrides@AttibuteOverride để ghi đè các thuộc tính cột của kiểu embedded của ta.

@Embedded
@AttributeOverrides({
  @AttributeOverride( name = "firstName", column = @Column(name = "contact_first_name")),
  @AttributeOverride( name = "lastName", column = @Column(name = "contact_last_name")),
  @AttributeOverride( name = "phone", column = @Column(name = "contact_phone"))
})
private ContactPerson contactPerson;

6. Kết luận

Trong bài viết này, ta đã định cấu hình một thực thể với một số thuộc tính nhúng và ánh xạ chúng vào cùng một bảng cơ sở dữ liệu với thực thể bao quanh. Để làm được điều đó, ta đã sử dụng các annotation @Embedded , @Embeddable , @AttributeOverrides@AttributeOverride do Java Persistence API cung cấp.