Wstęp
Obiekty wbudowane stosuje się w przypadku rozbieżności modelu obiektowego i fizycznego modelu bazodanowego. Przykładowo z bytem Użytkownik jest związany byt Adres. W modelu obiektowym byty te będą implementowane przez odrębne obiekty, jednak w relacyjnej bazie danych w celu osiągnięcia lepszej wydajności mogą być zaimplementowane przy użyciu jednej tabelki, zawierającej dane zarówno Użytkownika jak i jego Adres. W tym przykładzie Adres będzie obiektem wbudowanym i będzie przynależeć do trwałego obiektu Użytkownik. Ważną cechą obiektów wbudowanych jest to, że nie mają swojej tożsamości trwałej (swojego identyfikatora) i nie mogą być współdzielone przez różne obiekty trwałe.Klasy wbudowywane
Klasa obiektu wbudowanego musi być oznaczona adnotacjąEmbeddable
. Nie oznacza się jej jako encji, tym bardziej nie określa się dla niej tabeli w bazie danych ani identyfikatora. Poza tym dla klasy wbudowywanej specyfikuje się mapowanie pól jak przypadku zwykłych encji.
Poniżej znajduje się przykład definicji klasy wbudowywanej - Adres:
package pl.dwalczak.jpapg2.model; import javax.persistence.Column; import javax.persistence.Embeddable; @Embeddable public class Address { private String city; private String postcode; private String street; private String number; @Column(length=50, nullable=false) public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Column(length=6, nullable=false) public String getPostcode() { return postcode; } public void setPostcode(String postcode) { this.postcode = postcode; } @Column(length=50, nullable=false) public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } @Column(length=10, nullable=false) public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } }
Umieszczanie obiektów wbudowywanych w obiektach trwałych
Pola klasy o typie oznaczonym jako wbudowywany opatruje się adnotacjąEmbedded
. Nie jest to jednak niezbędne, gdyż specyfikacja JPA nakłada obowiązek na EntityManager aby sam wybadał sprawę na podstawie adnotacji Embeddable
, którym jest opatrzona klasa danego pola. Pola obiektu wbudowanego są mapowane na kolumny tabeli encji, do której przynależy.
Nadpisywanie atrybutów mapowania
JPA umożliwia nadpisywanie atrybutów mapowania zdefiniowanych w klasie wbudowywanej. W tym celu używa się adnotacjiAttributeOverrides
, która zawiera listę adnotacji AttributeOverride
. I te dopiero służą do nadpisywania mapowania poszczególnych pól klasy. Mechanizm nadpisywania atrybutów mapowania daje duże możliwości w kontekście wielokrotnego wykorzystania definicji klas wbudowywancyh.
Poniżej znajduje się przykład encji, w skład której wchodzą dwa obiekty wbudowane o typie Adres (stały adres zamieszkania i adres korespondencyjny).
package pl.dwalczak.jpapg2.model; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQuery; import javax.persistence.SequenceGenerator; import javax.persistence.Table; @NamedQuery( name="user.findByNickName", query="select u from User u where u.nickName = :nickName" ) // Definicja sekwencji "users_seq" służącej do generowania klucza głównego tabeli "users". @SequenceGenerator(name="users_seq") // Mapowanie tabeli "users". @Entity @Table(name="users") public class User { private Long id; private String nickName; private Address address; private Address mailingAddress; @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_seq") @Column(name="usr_id") public Long getId() { return id; } protected void setId(Long id) { this.id = id; } @Column(name="usr_nickname", unique=true, nullable=false, length=24) public String getNickName() { return nickName; } public void setNickName(String name) { this.nickName = name; } @Embedded public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Embedded @AttributeOverrides({ @AttributeOverride(name="city", column=@Column(name="ma_city")), @AttributeOverride(name="postcode", column=@Column(name="ma_postcode")), @AttributeOverride(name="street", column=@Column(name="ma_street")), @AttributeOverride(name="number", column=@Column(name="ma_number")) }) public Address getMailingAddress() { return mailingAddress; } public void setMailingAddress(Address mailingAddress) { this.mailingAddress = mailingAddress; } }
Zasoby
Pliki źródłowe przykładuHibernate Annotations - 2.2.2.3. Embedded objects (aka components)
Specyfikacja JPA
Brak komentarzy:
Prześlij komentarz