Come creare e gestire la chiave primaria composita in JPA


108

Voglio avere versioni dalla stessa immissione di dati. In altre parole, voglio duplicare la voce con un altro numero di versione.

id - Version sarà la chiave primaria.

Come dovrebbe apparire l'entità? Come posso duplicarlo con un'altra versione?

id Version ColumnA

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

Quando si utilizza l' @IdClassannotazione, un altro suggerimento che ho trovato è che l' @Columnannotazione dovrebbe andare nei campi della classe Entity ( YourEntitynel codice di esempio di RohitJan).
KenSV

Risposte:


231

Puoi creare un Embedded class, che contiene le tue due chiavi, e quindi avere un riferimento a quella classe come EmbeddedIdnel tuo Entity.

Avresti bisogno delle annotazioni @EmbeddedIde @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 **/
}

Un altro modo per ottenere questo compito è usare l' @IdClassannotazione e inserire entrambi i tuoi idin quello IdClass. Ora puoi usare la normale @Idannotazione su entrambi gli attributi

@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
È possibile utilizzare @Generatedvalueper gli ID di EmbeddedId
Kayser

1
@Kayser. Per quanto ne so. No. Devi impostare esplicitamente il valore per loro nella tua istanza KeyClass e quindi impostare quell'istanza della classe chiave nella tua Entity.
Rohit Jain

@Kayser. @GeneratedValuepuò essere utilizzato solo per generare valori chiave per una chiave primaria, non può generare combinazioni per chiavi composite.
Rohit Jain

1
@RohitJain solo una cosa: in realtà non puoi rendere pubblica la classe incorporata (deve essere nel proprio file per essere pubblica)
Lucas

1
@FastEngy È ancora possibile accedervi tramite Wayback Machine: web.archive.org/web/20170123035517/http://uaihebert.com/… . Sembra che questo articolo sia stato sostituito da web.archive.org/web/20170202203555/http://uaihebert.com/… e web.archive.org/web/20161014051056/http://uaihebert.com/… anch'esso scomparso ...
radlan

9

La classe MyKey deve essere implementata Serializablese stai usando@IdClass


5

Classe chiave:

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

Classe entità:

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

Come posso duplicarlo con un'altra versione?

È possibile scollegare l'entità che è stata recuperata dal provider, modificare la chiave di Entry e quindi renderla persistente come nuova entità.


È possibile definire l'id in Entrykey AUTOGENERATED. o qualcosa del genere @GeneratedValue(strategy = GenerationType.IDENTITY)
Kayser

1
Mi chiedo anche come calcolare l'hash per 2 chiavi primarie lunghe. Per quanto riguarda hashe primenel metodo hashCodein classe EntryKey, mi puoi dire dove l'idea viene?
Bruce Sun

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.