Cara membuat dan menangani kunci utama komposit di JPA

108

Saya ingin memiliki versi dari entri data yang sama. Dengan kata lain, saya ingin menggandakan entri tersebut dengan nomor versi lain.

id - Version akan menjadi kunci utama.

Seperti apa bentuk entitas tersebut? Bagaimana saya bisa menggandakannya dengan versi lain?

id Version ColumnA

1   0      Some data
1   1      Some Other data
2   0      Data 2. Entry
2   1      Data
Kayser
sumber
Saat menggunakan @IdClassanotasi, tip lain yang saya temukan adalah @Columnanotasi harus masuk ke bidang kelas Entitas ( YourEntitydalam kode contoh RohitJan).
KenSV

Jawaban:

231

Anda dapat membuat Embedded class, yang berisi dua kunci Anda, dan kemudian memiliki referensi ke kelas tersebut seperti EmbeddedIdpada Anda Entity.

Anda akan membutuhkan anotasi @EmbeddedIddan @Embeddable.

@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 **/
}

Cara lain untuk mencapai tugas ini adalah dengan menggunakan @IdClassanotasi, dan menempatkan keduanya iddi dalamnya IdClass. Sekarang Anda dapat menggunakan @Idanotasi normal pada kedua atribut

@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
sumber
4
Apakah mungkin digunakan @Generatedvalueuntuk Id oleh EmbeddedId
Kayser
1
@Tokopedia Sejauh yang aku tahu. Tidak. Anda harus secara eksplisit menetapkan nilai untuk mereka dalam instance KeyClass Anda, dan kemudian menetapkan instance kelas kunci tersebut di Entitas Anda.
Rohit Jain
@Tokopedia @GeneratedValuehanya dapat digunakan untuk menghasilkan nilai kunci untuk kunci utama, tidak dapat membuat kombinasi untuk kunci komposit.
Rohit Jain
1
@RohitJain hanya satu hal: Anda sebenarnya tidak dapat membuat kelas yang disematkan menjadi publik (perlu berada dalam file sendiri untuk menjadi publik)
Lucas
1
@FastEngy Masih dapat diakses melalui Wayback Machine: web.archive.org/web/20170123035517/http://uaihebert.com/… . Tampaknya artikel ini digantikan oleh web.archive.org/web/20170202203555/http://uaihebert.com/… dan web.archive.org/web/20161014051056/http://uaihebert.com/… yang juga menghilang …
radlan
9

Kelas MyKey harus diimplementasikan Serializablejika Anda menggunakan@IdClass

Swapnil17
sumber
5

Kelas kunci:

@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;
}

Kelas entitas:

@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;
    ...
}

Bagaimana saya bisa menggandakannya dengan Versi lain?

Anda dapat melepaskan entitas yang diambil dari penyedia, mengubah kunci Entri, lalu mempertahankannya sebagai entitas baru.

callfarc0de
sumber
Apakah mungkin untuk menentukan id di Entrykey AUTOGENERATED. atau sesuatu seperti itu @GeneratedValue(strategy = GenerationType.IDENTITY)
Kayser
1
Saya juga bertanya-tanya bagaimana cara menghitung hash untuk 2 kunci utama yang panjang. Mengenai hashdan primemetode hashCodedi kelas EntryKey, dapatkah Anda memberi tahu saya dari mana ide itu berasal?
Bruce Sun
1

Kelas MyKey (@Embeddable) tidak boleh memiliki hubungan seperti @ManyToOne

Ranuka
sumber
Kenapa tidak? Sudahkah Anda melihat contoh ini ?
Buhake Sindi