2012-10-23 19 views
71

Voglio avere le versioni dalla stessa voce di dati. In altre parole, voglio duplicare la voce con un altro numero di versione.Come creare e gestire la chiave primaria composita in JPA

id - Version sarà la chiave primaria.

Come dovrebbe essere 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 

risposta

158

Si può fare un Embedded class, che contiene i due tasti, e poi hanno un riferimento a tale classe come EmbeddedId nel vostro Entity.

Avresti bisogno delle annotazioni @EmbeddedId e @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 realizzare questo compito è quello di utilizzare @IdClass annotazioni, e posizionare sia il id in quel IdClass. Ora è possibile utilizzare il normale @Id annotazioni 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; 
} 
+0

È possibile utilizzare '@ Generatedvalue' per Id's di EmbeddedId – Kayser

+1

@Kayser. Per quanto ne so. No. Devi impostare esplicitamente il valore per loro nell'istanza KeyClass, quindi impostare l'istanza della classe chiave nell'entità. –

+0

@Kayser. '@ GeneratedValue' può essere utilizzato solo per generare valori chiave per una chiave primaria, non può generare combinazioni per chiavi composite. –

2

classe Key:

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

Entity classe:

@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 duplicarlocon un'altra versione?

È possibile scollegare l'entità recuperata dal provider, modificare la chiave di immissione e quindi mantenerla come nuova entità.

+0

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

+1

Mi chiedo anche come calcolare hash per 2 lunghe chiavi primarie. Per quanto riguarda 'hash' e' prime' nel metodo 'hashCode' nella classe' EntryKey', puoi dirmi da dove viene questa idea? –

4

La classe deve implementare MyKey Serializable se si utilizza @IdClass

0

La classe MyKey (@Embeddable) non dovrebbe avere relazioni come @ManyToOne

-1

Quando si utilizza il @IdClass annotazione, un altro suggerimento che ho trovato è il L'annotazione @Column deve essere inserita nei campi della classe Entity (YourEntity nel codice di esempio di RohitJan).

Problemi correlati