2012-10-23 3 views
71

Ich möchte Versionen aus dem gleichen Dateneintrag haben. Mit anderen Worten, ich möchte den Eintrag mit einer anderen Versionsnummer duplizieren.Wie erstellt und behandelt Composite-Primärschlüssel in JPA

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

Wie sollte die Entität aussehen? Wie kann ich es mit einer anderen Version duplizieren? in Ihrem Entity

id Version ColumnA 

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

Antwort

158

Sie können eine Embedded class, machen die Ihre zwei Schlüssel enthält, und dann einen Verweis als EmbeddedId zu dieser Klasse haben.

Sie würden die @EmbeddedId und @Embeddable Anmerkungen 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 erreichen, ist @IdClass Anmerkung zu verwenden, und legen Sie beide Ihre id in diesem IdClass. Jetzt können Sie normale @Id Anmerkung auf beide verwenden die Attribute

@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

Ist es möglich, '@ Generatedvalue' für Ids von EmbeddedId – Kayser

+1

@ Kayser zu verwenden. 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. –

+0

@Kayser. '@ GeneratedValue' kann nur zum Generieren von Schlüsselwerten für einen Primärschlüssel verwendet werden, er kann keine Kombination für zusammengesetzte Schlüssel generieren. –

2

Key-Klasse:

@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 Klasse:

@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 duplizieren mit einer anderen Version?

Sie können Entitäten trennen, die vom Provider abgerufen wurden, den Schlüssel von Entry ändern und ihn dann als neue Entität beibehalten.

+0

Ist es möglich das zu definieren? ID im Entrykey 'AUTOGENERATED'. oder so etwas '@GeneratedValue (strategie = GenerationType.IDENTITY)' – Kayser

+1

Ich frage mich auch, wie Hash für 2 lange Primärschlüssel zu berechnen ist. Was "hash" und "prime" in der Methode 'hashCode' in der Klasse' EntryKey' betrifft, kannst du mir sagen, woher diese Idee kommt? –

4

Die MyKey Klasse Serializable implementieren müssen, wenn Sie @IdClass

0

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

-1

verwenden Wenn die @IdClass Anmerkung verwenden, ich ein weiterer Tipp ist die gefunden @Column Annotation sollte in die Felder der Entity-Klasse (YourEntity in RohitJan Beispielcode) gehen.