Speichern einer Map <String, String> mit JPA


103

Ich frage mich, ob es möglich ist, mithilfe von Anmerkungen die attributesKarte in der folgenden Klasse mit JPA2 beizubehalten

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

Da wir bereits eine bereits vorhandene Produktionsdatenbank haben, können die Werte von idealerweise attributes der folgenden vorhandenen Tabelle zugeordnet werden:

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

Antworten:


201

JPA 2.0 unterstützt Sammlungen von Grundelementen durch die @ElementCollectionAnnotation, die Sie in Verbindung mit der Unterstützung von java.util.MapSammlungen verwenden können. So etwas sollte funktionieren:

@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

}

Siehe auch (in der JPA 2.0-Spezifikation)

  • 2.6 - Sammlungen eingebetteter Klassen und Grundtypen
  • 2.7 Kartensammlungen
  • 10.1.11 - ElementCollection-Annotation
  • 11.1.29 MapKeyColumn-Anmerkung

1
Gibt es eine Problemumgehung, um dies mit JPA 1 zu tun? Ich habe nur Beispiele mitMap<String, SomeOtherClass>
L. Holanda

3
Erwähnenswert könnte sein, dass example_attributeses einen zusammengesetzten Schlüssel geben sollte (example_id, name)- was hbm2ddl daraus generiert.
James Bassett

Ich habe das obige Beispiel versucht, aber beim Versuch, eine Entität beizubehalten, wird eine Ausnahme angezeigt: Sie müssen mindestens eine Zuordnung für diese Tabelle definieren. Abfrage: InsertObjectQuery (null). Irgendwelche Hinweise? Ich erstelle eine leere Entität, setze die Eigenschaftenzuordnung und versuche dann, sie beizubehalten.
Kamila

2
Mit MariaDB bin ich darauf Specified key was too long; max key length is 767 bytesgestoßen. Der Primärschlüssel, den es zu erstellen versucht, ist eine Kombination aus varchar (255) und @JoinColumn, die die Standardspaltengröße überschreitet. Sie müssen entweder Ihre Datenbank ändern oder Ihre @ MapKeyColumn ändern, um eine Länge bereitzustellen:@MapKeyColumn(name="name", length=100)
Jon

17
  @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>();

Dies ist ein Beispiel zum Einrichten einer Karte mit Kontrolle über Spalten- und Tabellennamen und Feldlänge.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.