Biblioteka(AndroMDA+JSF+Spring+JPA) -część V- mapowanie relacji

No i się doczekałem :) konfiguracja skończona. Wreszcie mam środowisko na którym mogę naprawdę się pobawić. Tak jak już pisałem zacznę od modelu dziedziny. Zanim jednak zamodeluję sobie kawałek aplikacji postanowiłem przyjrzeć się jak wygląda kod encji wygenerowany przez framework.Oto krótki przegląd mojego eksperymentu.

Relacje @One-To-One


Asocjacja dwukierunkowa
Na początek spróbuję sprawdzić relację One-To-One zamodelowaną za pomocą relacji asocjacji dwukierunkowej.


Kod po stronie klasy Przedsiebiorca.java
@OneToOne(mappedBy = "przedsiebiorca")
public Adres getAdresDzialalnosciGospodarczej()
{
return this.adresDzialalnosciGospodarczej;
}

Kod po stronie klasy Adres.java
@OneToOne(mappedBy = "adresDzialalnosciGospodarczej")
public Przedsiebiorca getPrzedsiebiorca()
{
return this.przedsiebiorca;
}

No i niestety... od razu problem, bo kod nie jest poprawny. Po obydwu stronach relacji wygenerowana została adnotacja z atrybutem "mappedBy" - framework nie poradził sobie z określeniem właściciela relacji. A więc tak się nie da. Skoro więc nie tak.. to pozostaje pytanie "jak"?
Wskazówkę niesie dokumentacja:

 "To model the owning side of a One-To-One or Many-To-Many bidirectional relationship, you indicate that end (the owning end) of the relationship as an aggregate or composite end. "

A więc wygląda na to, że dwukierunkowa  relacja pomiędzy encjami musi być modelowana przy pomocy agregacji lub kompozycji...Szkoda, bo przecież nie każdy związek pomiędzy obiektami to od razu agregacja lub kompozycja...

Agregacja dwukierunkowa
No to skoro wiem, co mówi teoria, pora spróbować praktyki, jeśli ma być agregacja, to niech będzie agregacja:

Kod po stronie klasy Przedsiebiorca.java
@OneToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "ADRES_DZIALALNOSCI_GOSPODAR_FK")
public Adres getAdresDzialalnosciGospodarczej()
{
return this.adresDzialalnosciGospodarczej;
}

Kod po stronie klasy Adres.java
@OneToOne(mappedBy = "adresDzialalnosciGospodarczej")
public Przedsiebiorca getPrzedsiebiorca()
{
return this.przedsiebiorca;
}

A więc tereaz generata jest w porządku. Właściciel relacji został prawidłowo wyodrębniony. Po jego stronie wygenerowany został klucz obcy - więc wygląda że wszystko jest ok.


Asocjacja jednokierunkowa
Relację skierowaną wypróbuję sobie na podstawie asocjacji.



Kod po stronie klasy Przedsiebiorca.java
@OneToOne(optional = false)
@JoinColumn(name = "ADRES_DZIALALNOSCI_GOSPODAR_FK")
public Adres getAdresDzialalnosciGospodarczej()
{
return this.adresDzialalnosciGospodarczej;
}

Kod po stronie klasy Adres.java
BRAK

A więc w przypadku relacji skierowanych, kod wygenerowany na podstawie asocjacji jest już całkowicie poprawny.

Relacje @One-To-Many



Asocjacja dwukierunkowa



Kod po stronie klasy Przedsiebiorca.java
@OneToMany(mappedBy = "przedsiebiorca")
public Set getAdresy()
{
return this.adresy;
}

Kod po stronie klasy Adres.java
@ManyToOne(optional = false)
@JoinColumn(name = "PRZEDSIEBIORCA_FK")
public Przedsiebiorca getPrzedsiebiorca()
{
return this.przedsiebiorca;
}

Powyższy kod jest poprawny, więc wygląda na to, że relacja @OneToMany może być modelowana przy pomocy relacji asocjacji dwukierunkowej.

Ale zaraz... coś tu jest nie tak... właścicielem relacji w UMLu jest klasa Przedsiebiorca.java, a klucz główny został wygenerowany po stronie Adres.java, dlaczego? A więc krótka wycieczka do specyfikacji "ejb-3_0-fr-spec-persistence" i wszystko jasne...
"The many side of one-to-many / many-to-one bidirectional relationships must be the owning
side, hence the mappedBy element cannot be specified on the ManyToOne annotation." 


Właściciel relacji po stronie JPA jest determinowany krotnością elementów, a nie kierunkiem relacji UML-owej. A więc wszystko jasne...

Agregacja dwukierunkowa




Kod po stronie klasy Przedsiebiorca.java
@OneToMany(mappedBy = "przedsiebiorca")
public Set getAdresy()
{
return this.adresy;
}

Kod po stronie klasy Adres.java
@ManyToOne(optional = false)
@JoinColumn(name = "PRZEDSIEBIORCA_FK")
public Przedsiebiorca getPrzedsiebiorca()
{
return this.przedsiebiorca;
}

Tutaj również wygenerowany kod jest poprawny.

Asocjacja jednokierunkowa



Kod po stronie klasy Przedsiebiorca.java
@OneToMany()
@JoinTable
(
name = "PRZEDSIEBIORCA2ADRESY",
joinColumns = {@JoinColumn(name = "PRZEDSIEBIORCA_ID_FK", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "ADRESY_ID_FK", referencedColumnName = "ID")}
)
public Set getAdresy()
{
return this.adresy;
}

Kod po stronie klasy Adres.java
Brak

Relacje @Many-To-Many

Znany cytat z dokumentacji AndroMDA mówi, że relacja @ManyToMany powinna być modelowana agregacją dwukierunkową.
 "To model the owning side of a One-To-One or Many-To-Many bidirectional relationship, you indicate that end (the owning end) of the relationship as an aggregate or composite end. "



Agregacja dwukierunkowa




Kod po stronie klasy Firma.java
@ManyToMany()
@JoinTable
(
name = "FIRMY2LOKALIZACJE",
joinColumns = {@JoinColumn(name = "FIRMY_ID_FK", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "LOKALIZACJE_ID_FK", referencedColumnName = "ID")}
)
public Set getLokalizacje()
{
return this.lokalizacje;
}

Kod po stronie klasy Lokalizacja.java
@ManyToMany(mappedBy = "lokalizacje")
public Set getFirmy()
{
return this.firmy;
}

A więc z tą relacją plugin również nie miał problemów. :)

Podsumowanie

Ten krótki przegląd możliwości pluginu w zakresie generowania encji przekonał mnie, że jest on frameworkiem wartym uwagi. Wygenerowany kod źródłowy jest dobrej jakości, a zachowanie pluginu przewidywalne i co rzadko spotykane - dobrze opisane w dokumentacji.
Następnym razem skupię się już na praktycznym zastosowaniu AndroMDA. Opiszę model dziedziny mojej małej aplikacji i sprawdzę czy wygenerowany kod działa na środowisku docelowym (a więc Spring + Tomcat)....

Tymczasem spaaaaać... :)...

1 komentarz:

gabrielsaccente pisze...

Casino Online Review | Play Real Money Slots at Top Casinos
Play Real Money Slots at Top Casinos · 1. 서울특별 출장샵 Wild 과천 출장샵 West Gold Slot 서귀포 출장마사지 Machine · 2. 순천 출장샵 Super Charming Jackpot Slot Machine 광명 출장마사지 · 3. Buffalo Gold Slot Machine · 4. Super