background image

Mapowanie związków 

pomiędzy obiektami

Rafał Kasprzyk

background image

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ń

background image

Rafał Kasprzyk

Relacje między klasami

Relacja jeden-do-wielu

background image

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

background image

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

}

background image

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>

background image

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

background image

Rafał Kasprzyk

OrganizationUnit.java

class OrganizationUnit {

//…

private Set persons=new HashSet();

public void setPersons(Set persons) {

this.persons = persons;

}

public Set getPersons() {

return persons;

}

}

background image

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> 

background image

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);

}

background image

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>

background image

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)

background image

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

}

background image

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>

background image

Rafał Kasprzyk

Podsumowanie

Reprezentacja związków 

Model relacyjny

Model obiektowy

Mapowanie asocjacji

Mapowanie dziedziczenia


Document Outline