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));
corydoras.dll
sumber

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
Pascal Thivent
sumber
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.

wciesiel.dll
sumber