Erstellen und Behandeln eines zusammengesetzten Primärschlüssels in JPA


108

Ich möchte Versionen von derselben Dateneingabe haben. Mit anderen Worten, ich möchte den Eintrag mit einer anderen Versionsnummer duplizieren.

id - Version wird der Primärschlüssel sein.

Wie soll das Unternehmen aussehen? Wie kann ich es mit einer anderen Version duplizieren?

id Version ColumnA

1   0      Some data
1   1      Some Other data
2   0      Data 2. Entry
2   1      Data

Ein @IdClassweiterer Tipp, den ich bei der Verwendung der Annotation gefunden habe, ist, dass die @ColumnAnnotation in die Felder der Entity-Klasse ( YourEntityim RohitJan-Beispielcode) aufgenommen werden sollte.
KenSV

Antworten:


231

Sie können ein erstellen Embedded class, das Ihre beiden Schlüssel enthält, und dann wie EmbeddedIdin Ihrem einen Verweis auf diese Klasse haben Entity.

Sie würden die @EmbeddedIdund @EmbeddableAnmerkungen benötigen .

@Entity
public class YourEntity {
    @EmbeddedId
    private MyKey myKey;

    @Column(name = "ColumnA")
    private String columnA;

    /** Your getters and setters **/
}
@Embeddable
public class MyKey implements Serializable {

    @Column(name = "Id", nullable = false)
    private int id;

    @Column(name = "Version", nullable = false)
    private int version;

    /** getters and setters **/
}

Eine andere Möglichkeit, diese Aufgabe zu erfüllen, besteht darin, @IdClassAnmerkungen zu verwenden und beide iddarin zu platzieren IdClass. Jetzt können Sie @Idfür beide Attribute normale Anmerkungen verwenden

@Entity
@IdClass(MyKey.class)
public class YourEntity {
   @Id
   private int id;
   @Id
   private int version;

}

public class MyKey implements Serializable {
   private int id;
   private int version;
}

4
Ist es möglich, @Generatedvaluefür IDs von EmbeddedId
Kayser

1
@ Kayser. Soweit ich weiss. Nein. Sie müssen den Wert für sie explizit in Ihrer KeyClass-Instanz festlegen und dann diese Schlüsselklasseninstanz in Ihrer Entität festlegen.
Rohit Jain

@ Kayser. @GeneratedValuekann nur zum Generieren von Schlüsselwerten für einen Primärschlüssel verwendet werden, es kann keine Kombination für zusammengesetzte Schlüssel generiert werden.
Rohit Jain

1
@RohitJain nur eine Sache: Sie können eingebettete Klasse tatsächlich nicht öffentlich machen (muss in einer eigenen Datei sein, um öffentlich zu sein)
Lucas

1
@FastEngy Es kann weiterhin über Wayback Machine zugegriffen werden: web.archive.org/web/20170123035517/http://uaihebert.com/… . Es scheint, dass dieser Artikel durch web.archive.org/web/20170202203555/http://uaihebert.com/… und web.archive.org/web/20161014051056/http://uaihebert.com/… ersetzt wurde, die ebenfalls verschwunden sind …
Radlan

9

Die MyKey-Klasse muss implementiert werden, Serializablewenn Sie verwenden@IdClass


5

Schlüsselklasse:

@Embeddable
@Access (AccessType.FIELD)
public class EntryKey implements Serializable {

    public EntryKey() {
    }

    public EntryKey(final Long id, final Long version) {
        this.id = id;
        this.version = version;
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getVersion() {
        return this.version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    public boolean equals(Object other) {
        if (this == other)
            return true;
        if (!(other instanceof EntryKey))
            return false;
        EntryKey castOther = (EntryKey) other;
        return id.equals(castOther.id) && version.equals(castOther.version);
    }

    public int hashCode() {
        final int prime = 31;
        int hash = 17;
        hash = hash * prime + this.id.hashCode();
        hash = hash * prime + this.version.hashCode();
        return hash;
    }

    @Column (name = "ID")
    private Long id;
    @Column (name = "VERSION")
    private Long operatorId;
}

Entitätsklasse:

@Entity
@Table (name = "YOUR_TABLE_NAME")
public class Entry implements Serializable {

    @EmbeddedId
    public EntryKey getKey() {
        return this.key;
    }

    public void setKey(EntryKey id) {
        this.id = id;
    }

    ...

    private EntryKey key;
    ...
}

Wie kann ich es mit einer anderen Version duplizieren?

Sie können die vom Anbieter abgerufene Entität trennen, den Eintragsschlüssel ändern und dann als neue Entität beibehalten.


Ist es möglich , die ID in Entrykey zu definieren AUTOGENERATED. oder so ähnlich @GeneratedValue(strategy = GenerationType.IDENTITY)
Kayser

1
Ich frage mich auch, wie man Hash für 2 lange Primärschlüssel berechnet. Was hashund primein Verfahren hashCodein der Klasse EntryKey, können Sie mir sagen , wo die Idee herkommt?
Bruce Sun

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.