2012-10-23 16 views
71

Chcę mieć wersje z tego samego wpisu danych. Innymi słowy, chcę zduplikować wpis z innym numerem wersji.Tworzenie i obsługa złożonego klucza podstawowego w JPA

id - Version będzie kluczem podstawowym.

Jak powinien wyglądać podmiot? Jak mogę go powielić w innej wersji?

id Version ColumnA 

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

Odpowiedz

158

Można dokonać Embedded class, który zawiera swoje dwa klucze, a następnie mieć odniesienie do tej klasy jako EmbeddedId w Entity.

Będziesz potrzebować adnotacji @EmbeddedId i @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 **/ 
} 

Innym sposobem osiągnięcia tego zadania jest użycie @IdClass adnotacji i umieść Zarówno id w tym IdClass. Teraz można korzystać z normalnego @Id adnotacji na obu atrybutów

@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

Czy można użyć '@ Generatedvalue' dla Id's by EmbeddedId – Kayser

+1

@Kayser. O ile mi wiadomo. Nie. Musisz jawnie ustawić dla nich wartość w instancji KeyClass, a następnie ustawić tę instancję klasy klucza w swojej encji. –

+0

@Kayser. '@ GeneratedValue' może być użyty tylko do wygenerowania kluczowych wartości klucza podstawowego, nie może generować kombinacji dla kluczy złożonych. –

2

Key klasa:

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

Podmiot klasa:

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

Jak mogę powielić go z inną wersją?

Można odłączyć encję, która została pobrana od dostawcy, zmienić klucz Entry, a następnie zachować go jako nowy podmiot.

+0

Możliwe jest zdefiniowanie id w Entrykey 'AUTOGENERATED'. Oder coś podobnego '@GeneratedValue (strategia = GenerationType.IDENTITY)' – Kayser

+1

Zastanawiam się również, jak obliczyć hash dla 2 długich kluczy podstawowych. Co do 'hash' i' prime' w metodzie 'hashCode' w klasie' EntryKey', czy możesz mi powiedzieć skąd ten pomysł pochodzi? –

4

Klasa MyKey musi wdrożyć Serializable jeśli używasz @IdClass

0

klasy MyKey (@Embeddable) nie powinny mieć żadnych relacji jak @ManyToOne

-1

Podczas korzystania z @IdClass adnotacji, kolejna wskazówka znalazłem to @Column adnotacja powinna iść do pól klasy jednostki (YourEntity w przykładowym kodzie RohitJana).

Powiązane problemy