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
Kayser
quelle
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;
}
Rohit Jain
quelle
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

Swapnil17
quelle
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.

callfarc0de
quelle
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
1

Die MyKey-Klasse (@Embeddable) sollte keine Beziehungen wie @ManyToOne haben

Ranuka
quelle
Warum nicht? Haben Sie sich dieses Beispiel angesehen ?
Buhake Sindi