Menyimpan Peta <String, String> menggunakan JPA


103

Saya ingin tahu apakah mungkin menggunakan anotasi untuk mempertahankan attributespeta di kelas berikut menggunakan JPA2

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

Karena kita sudah memiliki database produksi yang sudah ada sebelumnya, idealnya nilai attributes dapat dipetakan ke tabel yang ada berikut ini:

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

Jawaban:


201

JPA 2.0 mendukung koleksi primitif melalui @ElementCollectionanotasi yang dapat Anda gunakan sehubungan dengan dukungan java.util.Mapkoleksi. Sesuatu seperti ini seharusnya bekerja:

@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

}

Lihat juga (dalam spesifikasi JPA 2.0)

  • 2.6 - Koleksi Kelas yang Dapat Disematkan dan Jenis Dasar
  • 2.7 Koleksi Peta
  • 10.1.11 - Anotasi ElementCollection
  • 11.1.29 Anotasi MapKeyColumn

1
Apakah ada solusi untuk melakukan ini menggunakan JPA 1? Saya hanya menemukan contoh denganMap<String, SomeOtherClass>
L.Holanda

3
Mungkin layak disebutkan bahwa example_attributesharus memiliki kunci komposit (example_id, name)- yang akan dihasilkan hbm2ddl dari atas.
James Bassett

Saya mencoba contoh di atas, tetapi ketika mencoba untuk mempertahankan entitas, saya mendapatkan pengecualian: Anda harus menentukan setidaknya satu pemetaan untuk tabel ini. Kueri: InsertObjectQuery (null). Ada petunjuk? Saya membuat entitas kosong dan mengatur peta properti, kemudian mencoba untuk bertahan.
Kamila

2
Menggunakan MariaDB, saya Specified key was too long; max key length is 767 bytesmelakukan ini. Kunci utama yang dicoba dibuat adalah kombinasi dari varchar (255) dan @JoinColumn, yang melebihi ukuran kolom default. Anda perlu mengubah database Anda atau memodifikasi @MapKeyColumn Anda untuk memberikan panjang:@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>();

Ini adalah contoh bagaimana menyiapkan peta dengan kontrol atas kolom dan nama tabel dan panjang bidang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.