Lưu trữ một Bản đồ <Chuỗi, Chuỗi> bằng JPA


103

Tôi đang tự hỏi liệu có thể sử dụng chú thích để duy trì attributesbản đồ trong lớp sau bằng JPA2 không

public class Example {
    long id;
    // ....
    Map<String, String> attributes = new HashMap<String, String>();
    // ....
}

Vì chúng tôi đã có cơ sở dữ liệu sản xuất từ ​​trước, nên lý tưởng nhất là các giá trị của attributes có thể ánh xạ đến bảng hiện có sau:

create table example_attributes {
    example_id bigint,
    name varchar(100),
    value varchar(100));

Câu trả lời:


201

JPA 2.0 hỗ trợ các tập hợp nguyên thủy thông qua @ElementCollectionchú thích mà bạn có thể sử dụng cùng với sự hỗ trợ của các java.util.Maptập hợp. Một cái gì đó như thế này sẽ hoạt động:

@Entity
public class Example {
    @Id long id;
    // ....
    @ElementCollection
    @MapKeyColumn(name="name")
    @Column(name="value")
    @CollectionTable(name="example_attributes", joinColumns=@JoinColumn(name="example_id"))
    Map<String, String> attributes = new HashMap<String, String>(); // maps from attribute name to value

}

Xem thêm (trong đặc tả JPA 2.0)

  • 2.6 - Tập hợp các lớp có thể nhúng và các loại cơ bản
  • 2.7 Bộ sưu tập bản đồ
  • 10.1.11 - Chú thích ElementCollection
  • 11.1.29 Chú thích MapKeyColumn

1
Có giải pháp nào để thực hiện việc này bằng JPA 1 không? Tôi chỉ tìm thấy các ví dụ vớiMap<String, SomeOtherClass>
L. Holanda

3
Có thể đáng nói là example_attributescần có một khóa tổng hợp (example_id, name)- đó là những gì hbm2ddl sẽ tạo ra từ phần trên.
James Bassett

Tôi đã thử ví dụ trên, nhưng khi cố gắng duy trì một thực thể, tôi nhận được một ngoại lệ: Bạn phải xác định ít nhất một ánh xạ cho bảng này. Truy vấn: InsertObjectQuery (null). Bất kỳ gợi ý? Tôi tạo một thực thể trống và đặt bản đồ thuộc tính, sau đó cố gắng tiếp tục.
Kamila

2
Sử dụng MariaDB, tôi đã Specified key was too long; max key length is 767 byteslàm được điều này. Khóa chính mà nó cố gắng tạo là sự kết hợp của varchar (255) và @JoinColumn, vượt quá kích thước cột mặc định. Bạn cần thay đổi cơ sở dữ liệu của mình hoặc sửa đổi @MapKeyColumn của bạn để cung cấp độ dài:@MapKeyColumn(name="name", length=100)
Jon

18
  @ElementCollection(fetch = FetchType.LAZY)
  @CollectionTable(name = "raw_events_custom", joinColumns = @JoinColumn(name =     "raw_event_id"))
  @MapKeyColumn(name = "field_key", length = 50)
  @Column(name = "field_val", length = 100)
  @BatchSize(size = 20)
  private Map<String, String> customValues = new HashMap<String, String>();

Đây là một ví dụ về cách thiết lập bản đồ có quyền kiểm soát tên cột và bảng và độ dài trường.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.