Mapowanie związków
pomiędzy obiektami
Rafał Kasprzyk
Rafał Kasprzyk
Reprezentacja związków
Jedna z ważniejszych różnic pomiędzy
modelem obiektowym i relacyjnym to sposób
reprezentacji związków
W modelu relacyjnym związku są reprezentowane
przez klucze obce w encjach podrzędnych
Najczęściej występujące związki to: 1-N i N-N
W modelu obiektowym związki maja bardziej
naturalna postać
Przyjmują postać referencji na encję bądź referencję na
kolekcje encji (asocjacja, agregacja, kompozycja)
Dziedziczenie
Nawigowanie po grafie obiektów jest dużo
wygodniejsze niż pomiędzy tabelami
Możliwe jest przechodzenie z encji podrzędnej do
nadrzędnej i na odwrót, bez konieczności
zadawania skomplikowanych zapytań
Rafał Kasprzyk
Relacje między klasami
Relacja jeden-do-wielu
Rafał Kasprzyk
Mapowanie asocjacji (strona N)
W kodzie klasy znajdującej się po
stronie N asocjacji encja nadrzędna
umieszczana jest jako właściwość
JavaBeans ze stosownymi metodami
dostępu
W pliku definicja mapowania dla
klasy znajdujące się po stronie N
asocjacji korzysta się ze znacznika
<many-to-one …/>
Znacznik specyfikuje m.in. nazwę
właściwości, typ obiektu nadrzędnego i
klucz obcy wskazujący na klucz główny
encji nadrzędnej
Rafał Kasprzyk
Person.java
public class Person {
private int id;
private String name;
private OrganizationUnit unit;
public OrganizationUnit getUnit() {
return unit;
}
public void setUnit(OrganizationUnit
unit){
this.unit = unit;
}
…
// pozostałe metody setXXX i getXXX
}
Rafał Kasprzyk
Person.hbm.xml
<hibernate-mapping
package="pl.isolution.hibernate">
<class name= "Person" table= "Person">
<id name= "id" column="ID">
<generator class="increment"/>
</id>
<property name="name"/>
<many-to-one
name="unit"
column="ORGANIZATION_UNIT_FK"
class="OrganizationUnit"
not-null="true"/>
</class>
</hibernate-mapping>
Rafał Kasprzyk
Mapowanie asocjacji (strona 1)
W kodzie klasy znajdującej się po stronie 1
asocjacji encje podrzędne umieszczane są
w kolekcjach ze stosownymi metodami
dostępu
W pliku definicja mapowania dla klasy
znajdujące się po stronie 1 asocjacji
korzysta się ze znacznika specyficznego
dla danego rodzaju kolekcji np. <Set …>
Znacznik specyfikuje m.in. nazwę właściwości,
typ obiektu podrzędnego i klucz obcy encji
podrzędnej wskazujący na klucz główny
rozpatrywanej encji, będącej encją nadrzędną
Jeżeli druga strona asocjacji (encja podrzędna)
ma mieć wskazanie na encję nadrzędną należy
ustawić parametr inverse = "true", co nadaje
asocjacji charakter dwukierunkowy
Rafał Kasprzyk
OrganizationUnit.java
class OrganizationUnit {
//…
private Set persons=new HashSet();
public void setPersons(Set persons) {
this.persons = persons;
}
public Set getPersons() {
return persons;
}
}
Rafał Kasprzyk
OrganizationUnit.hbm.xml
<hibernate-mapping>
<class name="OrganizationUnit"
table="OrganizationUnit">
…
<set name="persons">
<key
column="ORGANIZATION_UNIT_FK"/>
<one-to-many class="Person"/>
</set>
</class>
</hibernate-mapping>
Rafał Kasprzyk
Przykładowy kod wykorzystujący
relacje
public void addPersonToUnit(int pId, int uId) {
Session session =
(Session) threadLocal.get();
if( session == null) {
session = sessionFactory.openSession();
threadLocal.set(session);
}
Transaction transaction =
session.beginTransaction();
Person person = (Person)
session.load(Person.class, pId);
OrganizationUnit unit = (OrganizationUnit)
session.load(OrganizationUnit.class, uId);
unit.getPersons().add(person);
transaction.commit();
session.close();
threadLocal.set(null);
}
Rafał Kasprzyk
Relacja wiele-do-wielu
<class name="Person" table="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>
<class name="Address" table="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<set name="people" inverse="true">
<key column="addressId"/>
<many-to-many column="personId" class="Person"/>
</set>
</class>
Rafał Kasprzyk
Mapowanie dziedziczenia
Model relacyjny nie przewiduje związku
dziedziczenia, co powoduje różnego
rodzaju problemy przy próbie jego
mapowania
Istnieją trzy metody odwzorowania
dziedziczenia w modelu relacyjnym:
Mapowanie obiektów każdej klasy do
osobnych tabel z powtarzaniem pól
Mapowanie całego drzewa dziedziczenia do
jednej tabeli
Najczęściej stosowane (proste zapytań SQL)
Mapowanie obiektów każdej klasy do
osobnych tabel bez powtarzania pól, ze
wskazaniem na tabele nadtypu
Najrzadziej stosowane (skomplikowane zapytania
SQL)
Rafał Kasprzyk
Dziedziczenie
public class Person {
Long id;
String name;
...
//metody setXXX i getXXX
}
public class Employee extends Person {
String NIP;
...
//metody setXXX i getXXX
}
Rafał Kasprzyk
Dziedziczenie
<class name="Person" table= "Person"
discriminator-value="P"
>
<id name="id">
<generator class="native"/>
</id>
<discriminator column="subclass"
type="character"/>
<property name="name" type="string"/>
<subclass name="Employee"
discriminator-value="E">
<property name="NIP" type="string"/>
</subclass>
</class>
Rafał Kasprzyk
Podsumowanie
Reprezentacja związków
Model relacyjny
Model obiektowy
Mapowanie asocjacji
Mapowanie dziedziczenia