W języku WZP istnieje kilka sposobów tworzenia złożonych pól kluczowych. Zobacz metodę wykorzystującą @Embeddable annotation
.
Zacznijmy od klasy Entity.
@Entity
@Table
public class TraceRecord {
@Id
private TraceRecordPk id;
@Version
@Transient
private int version;
@Column(columnDefinition = "char")
private String durationOfCall;
@Column(columnDefinition = "char")
private String digitsDialed;
@Column(columnDefinition = "char")
private String prefixCalled;
@Column(columnDefinition = "char")
private String areaCodeCalled;
@Column(columnDefinition = "char")
private String numberCalled;
}
Jest to całkiem prosta klasa jednostek z polem @Id i @Version oraz kilkoma definicjami @Column. Nie wdając się w szczegóły, zauważysz, że pole @Version również zawiera adnotację @Transient. Zrobiłem to po prostu dlatego, że mój stół również nie ma kolumny do śledzenia wersji, ale moja baza danych jest kronikowana, więc nie jestem zbytnio zaniepokojony wersjonowaniem. Zauważysz również, że pola @Column mają wartość "char" ustawioną w atrybucie columnDefinition. Dzieje się tak dlatego, że pola w mojej tabeli są zdefiniowane jako char, a nie varchar. Gdyby byli varchar, nie musiałbym tego robić, ponieważ String domyślnie mapuje do pola varchar.
Pole @Id
jest tym, co mnie interesuje właśnie teraz. Nie jest to standardowy typ Java, ale klasa, którą sam zdefiniowałem. Oto ta klasa.
@Embeddable
public class TraceRecordPk implements Serializable {
private static final long serialVersionUID = 1L;
@Temporal(TemporalType.DATE)
@Column
private Date dateOfCall;
@Column(columnDefinition="char")
private String timeOfCall;
@Column(columnDefinition="char")
private String callingParty;
/**
* Constructor that takes values for all 3 members.
*
* @param dateOfCall Date the call was made
* @param timeOfCall Time the call was made
* @param callingParty Extension from which the call originated
*/
public TraceRecordPk(Date dateOfCall, String timeOfCall, String callingParty) {
this.dateOfCall = dateOfCall;
this.timeOfCall = timeOfCall;
this.callingParty = callingParty;
}
}
Aby ta klasa zdolne do pola @Id na klasy Entity, musi być opatrzone @Embeddable jak wspominałem wcześniej. Trzy pola wybrane dla mojego klucza złożonego są po prostu normalnymi definicjami @Column. Zamiast tworzyć obiekty pobierające/ustawiające dla każdego pola, po prostu zaimplementowałem konstruktor, który przyjmuje wartości dla wszystkich 3 pól, czyniąc każdą instancję niezmienną. Podczas adnotowania klasy za pomocą @Embeddable, ta klasa będzie musiała zaimplementować Serializable. Dlatego dodałem domyślny identyfikator serialVersionUID, aby się do niego dostosować.
Teraz, gdy masz klasę utworzoną i opatrzoną adnotacją z @Embeddable
, możesz teraz używać jej jako typu dla pola @Id w klasie Entity. Proste rzeczy eh.
Przypuszczam, że mogę używać Embeddable z ElementCollection. Nie muszę używać @Embedded rt? – shazinltc
Nie dostałem twojego trzeciego punktu. – shazinltc
Trzeci punkt: rozważ Osobę zawiera Adres (osadzony), jeśli istnieje osobna tabela dla obu, Możesz bezpośrednio usunąć powiązany adres, ale jeśli tabela Osoby ma F.K. do adresowania, może to spowodować naruszenie ograniczenia integralności. – deepakraut