0% found this document useful (0 votes)
9 views

Module 03 - Hibernate Association Mapping-upd

Uploaded by

surafelbehailu90
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

Module 03 - Hibernate Association Mapping-upd

Uploaded by

surafelbehailu90
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

Module 03: Association Mapping

CS544: Enterprise Architecture

© 2014 Time2Master 1
Association Mapping
 In Java associations are made with object
references
public class Person { public class Car {
private int id; private int id;
Person has a private String firstname; private short year;
cars collection private String lastname; private String model; Car also has an
of references private List<Car> cars private String maker; owner reference
= new ArrayList(); private Person owner; back to its owner
... ...

 In a relational schema associations are made with


Foreign keys
Car has a foreign
key to Person

 O/R Mapping translates references into foreign


keys and visa versa.
© 2014 Time2Master 2
OO Association Directionality
 Uni-directional association Person

+firstname
+lastname
owns
Car

+year
+model
1 0..*
+birthday +maker
+cars
Can only be traversed
from person to car
public class Person { public class Car {
private int id; private int id;
Person has a private String firstname; private short year;
collection of private String lastname; private String model; Car does not have
references to private List<Car> cars private String maker; a reference back
Car objects = new ArrayList(); to person
...
...

Person Car

 Bi-directional association
owns
+firstname +year
+lastname +model
1 0..*
+birthday +maker
+cars +owner
Association Can be
traversed in both directions
public class Person { public class Car {
Person has a private int id; private int id;
private String firstname; private short year;
collection of Car also has a
private String lastname; private String model;
references to private List<Car> cars private String maker; reference back
Car objects = new ArrayList(); private Person owner; to person
... © 2014 Time2Master ...
3
Seven Types of Associations
 There are seven types of associations
 4 Uni-directional
 3 Bi-directional
Multiplicity Uni-Directional Bi-directional
One To One Uni-Directional Bi-Directional
Many To One Uni-Directional
Bi-Directional
One To Many Uni-Directional
Many To Many Uni-Directional Bi-Directional

 One to Many and Many to One are different


sides of the same bi-directional association

© 2014 Time2Master 4
Association Mapping

MANY TO ONE ASSOCIATIONS

© 2014 Time2Master 5
Many to One Uni-Directional
 Objects A Car has one Customer
and a Customer can be
the owner of more than
Car Customer one Car
+year owned by +firstname
+model +lastname
+maker 0..* 1
+owner

 Database The CAR table has a


foreign key of the
CAR table customer

The foreign key


column is always at
the many site.
CUSTOMER table

© 2014 Time2Master 6
Many to One Uni-Directional
@Entity @Entity
public class Car { public class Customer {
@Id Optional @Id
@GeneratedValue @JoinColumn @GeneratedValue
private int id; to specify the private int id;
private short year; private String firstname;
FK column private String lastname;
@ManyToOne private String model;
private String maker;
name
@ManyToOne ...
@JoinColumn(name="customer_id")
private Customer customer;

...

CAR table
Car Customer
+year owned by +firstname
+model +lastname
+maker 0..* 1
+owner

CUSTOMER table

© 2014 Time2Master 7
Uni-directional Many to One XML
public class Car {
<hibernate-mapping package="manyToOne_uni"> private int id;
<class name="Car" > private short year;
<id name="id"> private String model;
<generator class="native"/> private String maker;
</id> private Customer customer;
<property name="year" />
<property name="model" /> ...
<property name="maker" />
<many-to-one name="customer" class="Customer“ <many-to-one> maps a FK
column="customer_id" />
column in the Car table
</class>
</hibernate-mapping>
As before the column
attribute is optional

public class Customer {


<hibernate-mapping package="manyToOne_uni"> private int id;
<class name="Customer" > private String firstname;
<id name="id"> private String lastname;
<generator class="native"/>
</id> ...
<property name="firstname" />
<property name="lastname" />
</class> Normal Customer class
</hibernate-mapping>

© 2014 Time2Master 8
Optional Associations
 Optional associations are associations that
may not exist
 A Car can exist without a Customer
Car Customer
+year owned by +firstname
0..1 indicates that the
+model +lastname customer association
+maker 0..* 0..1
+owner is optional

CAR table

CUSTOMER table To facilitate this


CUSTOMER_ID would
have to be nullable

© 2014 Time2Master 9
Avoid Nullable FK Columns
 Nullable columns are generally frowned upon
since they break normalization
 To avoid nullable foreign key columns on
optional associations you can use a join table
for an optional many to one associations :

CAR table CAR_CUSTOMER table CUSTOMER table

Join table to store the Car-


Customer association

© 2014 Time2Master 10
Optional Many to One (join table)
Normally mapped
Customer class
@Entity @Entity
public class Car { public class Customer {
@Id @Id
@GeneratedValue @JoinTable and @GeneratedValue
private int id; the join table private int id;
private short year; name are private String firstname;
@ManyToOne private String model; required private String lastname;
private String maker;
@ManyToOne ...
@JoinTable(name="car_customer")
private Customer customer;

...

Car Customer
+year owned by +firstname
+model +lastname
+maker 0..* 0..1
+owner

© 2014 Time2Master 11
Optional Many to One XML
<hibernate-mapping package="manyToOne_uni"> public class Car {
<class name="Car" > private int id;
<id name="id"> private short year;
<generator class="native"/> private String model;
</id> private String maker;
<join> is used to private Customer customer;
<property name="year" />
<property name="model" /> specify the join table
<property name="maker" /> ...
<join table="car_customer" optional="true">
<key column="car_id" />
<many-to-one name="customer" class="Customer" <many-to-one> now maps a
column="customer_id" />
</join>
FK column in the join table
</class>
</hibernate-mapping>

public class Customer {


<hibernate-mapping package="manyToOne_uni"> private int id;
<class name="Customer" > private String firstname;
<id name="id"> private String lastname;
<generator class="native"/>
</id> ...
<property name="firstname" />
<property name="lastname" />
</class> Normal Customer class
</hibernate-mapping>

© 2014 Time2Master 12
Association Mapping

ONE TO MANY ASSOCIATIONS

© 2014 Time2Master 13
One to Many Uni-directional
 Objects Person
owns
Car
+firstname +year
+lastname +model
1 0..*
+cars +maker

Default
 Database (2 options)
PERSON table PERSON table

FK column on
CAR table the many side PERSON_CAR table
Join
table

CAR table

© 2014 Time2Master 14
One to Many Uni-Directional FK
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
@OneToMany private String firstname;
private String lastname; Collection of car references
@OneToMany
@JoinColumn(name="person_id")
private List<Car> cars = new ArrayList();

...

Normal mapping
of Car class
Person Car
owns @Entity
+firstname +year
+lastname +model public class Car {
1 0..*
+cars +maker
@Id
@GeneratedValue
private int id;
private short year;
Using a FK on private String model;
the many side private String maker;

...

© 2014 Time2Master 15
Uni–directional One to Many FK XML
public class Person {
<hibernate-mapping package="oneToMany_uniFK"> private int id;
<class name="Person" > private String firstname;
<id name="id"> private String lastname;
<generator class="native"/> private List<Car> cars =
</id> A <key> tag to new ArrayList();
<property name="firstname" /> specify a foreign key
<property name="lastname" /> join column in Car ...
<bag name="cars">
<key column="person_id" />
<one-to-many class="Car"/>
</bag>
</class>
</hibernate-mapping>
<one-to-many> tag to
map the FK relation

public class Car {


<hibernate-mapping package="oneToMany_uniFK"> private int id;
<class name="Car" > private short year;
<id name="id"> private String model;
<generator class="native"/> private String maker;
</id>
<property name="year" /> ...
<property name="model" />
<property name="maker" />
</class> Regular mapping of
</hibernate-mapping> the Car class
© 2014 Time2Master 16
One to Many Uni-directional
@Entity
public class Person {
@Id
@GeneratedValue Optional @JoinTable to
private int id;
@OneToMany private String firstname; specify the join table
private String lastname; name and columns
@OneToMany
@JoinTable(name = "person_car",
joinColumns = { @JoinColumn(name = "Person_id") },
inverseJoinColumns = { @JoinColumn(name = "Car_id") }
)
private List<Car> cars = new ArrayList<Car>();

...
Normal mapping
Person Car of Car class
owns @Entity
+firstname +year
+lastname +model public class Car {
1 0..*
+cars +maker
@Id
@GeneratedValue
private int id;
private short year;
private String model;
private String maker;

...

© 2014 Time2Master 17
Uni-direction One to Many XML
public class Person {
<hibernate-mapping package="oneToMany_uni"> private int id;
<class name="Person" > private String firstname;
<id name="id"> <bag> maps the private String lastname;
<generator class="native"/> collection and can specify private List<Car> cars =
</id> new ArrayList();
the join table name
<property name="firstname" />
<property name="lastname" /> ...
<bag name="cars" table="person_car">
<key column="person_id" />
<many-to-many column="car_id" unique="true" class="Car"/>
</bag>
</class> <many-to-many> used for join table
</hibernate-mapping> mappings ‘unique’ constrains it to
<one-to-many> functionality

public class Car {


<hibernate-mapping package="oneToMany_uni"> private int id;
<class name="Car" > private short year;
<id name="id"> private String model;
<generator class="native"/> private String maker;
</id>
<property name="year" /> ...
<property name="model" />
<property name="maker" />
</class> Normal mapping of
</hibernate-mapping> the Car class
© 2014 Time2Master 18
Many to One / One to Many (Bi)
@Entity @Entity
public class Person { public class Car {
@Id @Id
@GeneratedValue @GeneratedValue
private int id; private int id;
private String firstname; private short year;
private String lastname; private String model;
@OneToMany private String maker;
@JoinColumn(name="person_id") @ManyToOne
private List<Car> cars = @JoinColumn(name="owner_id")
new ArrayList(); private Person owner;

... ...
This OneToMany association is stored This ManyToOne association is stored
in the foreign key column with name in the foreign key column with name
‘person_id’ in the CAR table ‘owner_id’ in the CAR table

PERSON table
Hibernate sees this bi-directional
association as 2 independent
associations

CAR table
Both FK column contain
the same information

© 2014 Time2Master 19
mappedBy
@Entity @Entity
public class Person { mappedby indicates public class Car {
@Id @Id
@GeneratedValue
that the FK is on the @GeneratedValue
private int id; other side private int id;
private String firstname; private short year; Optional
private String lastname; private String model; @JoinColumn
@OneToMany(mappedBy="owner") private String maker; to specify FK
private List<Car> cars = @ManyToOne
new ArrayList(); @JoinColumn(name="owner_id")
private Person owner;
...
...

The bi-directional
association is stored in
one FK colunm

PERSON table CAR table

© 2014 Time2Master 20
Many to One / One to Many XML
public class Car {
<hibernate-mapping package="oneToMany_uni"> private int id;
<class name="Car" > private short year;
<id name="id"> private String model;
<generator class="native"/> private String maker;
</id> private Person owner;
<many-to-one> creates a FK
<property name="year" />
<property name="model" /> column to the Person table ...
<property name="maker" />
<many-to-one name="owner" column="owner_id" class="Person" />
</class>
</hibernate-mapping>

public class Person {


<hibernate-mapping package="oneToMany_uni"> private int id;
<class name="Person" > private String firstname;
<id name="id"> inverse specifies that the private String lastname;
<generator class="native"/> FK is on the other side private List<Car> cars =
</id> new ArrayList();
<property name="firstname" />
<property name="lastname" /> ...
<bag name="cars" inverse="true">
<key column="owner_id" /> <key> specifies the
<one-to-many class="Car"/> name of the FK column
</bag>
</class>
</hibernate-mapping>

© 2014 Time2Master 21
Association Mapping

ONE TO ONE ASSOCIATIONS

© 2014 Time2Master 22
OneToOne Uni-Directional
 Objects Address
OneToOne means that
Customer
+street only one Customer can
location
+firstname +suiteOrApt
+lastname +city live at a certain address
+address 1 1
+state
+zip

 Database
CUSTOMER table ADDRESS table

Shared primary key

© 2014 Time2Master 23
OneToOne and ManyToOne
Only one Customer can live at
 OneToOne a certain address

CUSTOMER table ADDRESS table

Shared primary key

More than one Customer can


 ManyToOne live at the same address

CUSTOMER table ADDRESS table

With a Unique constriant this


Foreign key is still basically a one-to-one
© 2014 Time2Master 24
Uni-directional OneToOne
 JPA does not support a shared PK OneToOne
@Entity
@Entity
public class Customer {
public class Address {
@Id
@Id
@GeneratedValue
@GeneratedValue
private int id;
private int id;
private String firstname;
private String street;
private String lastname;
@OneToOne private String suiteOrApt;
@OneToOne
private String city;
private Address address;
private String state;
private String zip;
...
...

 This mapping results in a ManyToOne with a


Unique Constraint (Therefore OneToOne)
CUSTOMER table ADDRESS table

© 2014 Time2Master 25
Unique Constriant XML
public class Customer {
private int id;
<hibernate-mapping package="oneToOne_uni"> private String firstname;
<class name="Customer" > private String lastname;
<id name="id"> private Address address;
<generator class="native"/>
</id> ...
<property name="firstname" />
<property name="lastname" />
<many-to-one name="address" class="Address" unique="true"/> many-to-one with a
</class> foreign key that is
</hibernate-mapping> Unique=true enforces unique
one to one behavior

<hibernate-mapping package="oneToOne_uni"> public class Address {


<class name="Address" > private int id;
<id name="id"> private String street;
<generator class="native"/> private String suiteOrApt;
</id> private String city;
<property name="street" /> private String state;
<property name="suiteOrApt" /> private String zip;
<property name="city" />
<property name="state" /> ...
<property name="zip" />
</class> Normal Address class
</hibernate-mapping>

© 2014 Time2Master 26
One to One Bi-directional
@Entity @Entity Other side
public class Customer { public class Address { also uses
@Id @Id @OneToOne
@GeneratedValue @GeneratedValue and specifies
private int id;
Optional
private int id;
private String firstname; @JoinColumn to
that the FK is
private String street;
private String lastname; specify FK name private String suiteOrApt; mappedBy
@OneToOne private String city; address
@JoinColumn(name="address_id") private String state;
private Address address; private String zip;
@OneToOne(mappedBy="address")
... private Customer customer;

...
mappedBy thus
specifies that
Address
Customer
this side is not
+street
+firstname
location
+suiteOrApt
the owning side
+lastname +city
+address 1 1
+state
+zip
+customer

© 2014 Time2Master 27
One to One bi-directional in XML
public class Customer {
<hibernate-mapping package="oneToOne_bi"> private int id;
<class name="Customer" > private String firstname;
<id name="id"> private String lastname;
<generator class="native"/> private Address address;
</id>
<property name="firstname" /> ...
<property name="lastname" />
<many-to-one name="address" class="Address" unique="true"/>
Unique=true constrains the
</class>
</hibernate-mapping> <many-to-one> creates a FK many-to-one into one-to-one
column to the Address table behavior

<hibernate-mapping package="oneToOne_bi"> public class Address {


<class name="Address" > private int id;
<id name="id"> private String street;
<generator class="native"/> private String suiteOrApt;
</id> private String city;
<property name="street" /> private String state;
<property name="suiteOrApt" /> private String zip;
<property name="city" /> private Customer customer;
<property name="state" />
<property name="zip" /> ...
<one-to-one name="customer" class="Customer"
property-ref="address"/> <one-to-one> specifies that the
</class> FK is mapped by address in
</hibernate-mapping> Customer, and thereby that this
side is not the owning side
© 2014 Time2Master 28
Shared PK Workaround:
@PrimaryKeyJoinColumn
Primary key
value not
@Entity generated @Entity
public class Customer { public class Address { Id has to be set
@Id @Id manually
@GeneratedValue private int id;
private int id; private String street;
private String firstname; @PrimaryKeyJoinColumn private String suiteOrApt;
private String lastname; Join on PK value private String city;
@OneToOne private String state;
@PrimaryKeyJoinColumn private String zip;
private Address address;
...
...

CUSTOMER table ADDRESS table

Shared primary key

© 2014 Time2Master 29
One to One Shared PK XML
public class Customer {
private int id;
<hibernate-mapping package="oneToOne_uni_PKJoin"> private String firstname;
<class name="Customer" > private String lastname;
<id name="id"> private Address address;
<generator class="native"/>
</id> ...
<property name="firstname" />
<property name="lastname" />
<one-to-one name="address" class="Address" /> One-to-one indicates
</class> that this reference is
</hibernate-mapping> mapped without FK

public class Address {


<hibernate-mapping package="oneToOne_uni_PKJoin"> private int id;
<class name="Address" > private String street;
<id name="id" /> private String suiteOrApt;
Again no PK private String city;
<property name="street" />
<property name="suiteOrApt" />
generation, private String state;
<property name="city" /> Id has to be private String zip;
<property name="state" /> set manually
<property name="zip" /> ...
</class>
</hibernate-mapping>

© 2014 Time2Master 30
One to One Shared PK
Bi-directional
@Entity
@Entity
public class Customer {
public class Address { Custom generator
@Id
AUTO generated @Id
@GeneratedValue
@GeneratedValue(generator="myGenerator")
private int id;
@org.hibernate.annotations.GenericGenerator(
private String firstname;
name="myGenerator",
private String lastname; Hibernate ‘foreign ‘ strategy
strategy="foreign",
@OneToOne
extension parameters=@Parameter(name="property",
@PrimaryKeyJoinColumn
value="customer")
private Address address;
)
Specify PK Join private int id;
Select value from
...
private String street;
private String suiteOrApt; customer PK
private String city;
Address private String state;
Customer
location
+street private String zip;
+firstname +suiteOrApt Also Specify PK
+lastname +city
@OneToOne
1 1
+address +state @PrimaryKeyJoinColumn Join on this side
+zip
+customer
private Customer customer;

...

© 2014 Time2Master 31
Shared PK XML
Bi-directional
public class Customer {
<hibernate-mapping package="oneToOne_bi_PKJoin">
private int id;
<class name="Customer" >
private String firstname;
<id name="id">
private String lastname;
<generator class="native"/>
private Address address;
</id>
<property name="firstname" />
...
<property name="lastname" />
<one-to-one name="address" class="Address" />
</class> <one-to-one> specifies no
</hibernate-mapping> additional FK

<hibernate-mapping package="oneToOne_bi_PKJoin"> public class Address {


<class name="Address" > private int id;
<id name="id"> private String street;
<generator class="foreign"> private String suiteOrApt;
<param name="property">customer</param> private String city;
</generator> private String state;
</id> private String zip;
<property name="street" /> Foreign strategy selects
private Customer customer;
<property name="suiteOrApt" /> pk from customer
<property name="city" /> ...
<property name="state" />
<property name="zip" />
<one-to-one name="customer" class="Customer" <one-to-one> specifies no additional FK
constrained="true" />
</class>
</hibernate-mapping> constrained attribute
adds FK constraint to PK
© 2014 Time2Master 32
Association Mapping

MANY TO MANY ASSOCIATIONS

© 2014 Time2Master 33
Many to Many Uni-directional
@Entity
public class Customer {
@Id
@GeneratedValue
private int id;
@ManyToMany private String firstname; Optional @JoinTable
private String lastname;
private String phoneNr;
@ManyToMany
@JoinTable(name = "Customer_SalesPerson",
joinColumns = { @JoinColumn(name = "Customer_id") },
inverseJoinColumns = { @JoinColumn(name = "SalesPerson_id") }
)
private List<SalesPerson> salesPeople = new ArrayList();

@Entity
Customer SalesPerson public class SalesPerson {
called by
+firstname +repId @Id
+lastname 0..* 1..* +alias
+phoneNr +phoneNr @GeneratedValue
+salesPeople private int id;
private String alias;
private String phoneNr;

...
Normal mapping of
SalesPerson class
© 2014 Time2Master 34
Uni-directional Many to Many XML
public class Customer {
private int id;
<hibernate-mapping package="manyToMany_uni"> private String firstname;
<class name="Customer" > private String lastname;
<id name="id"> private List<SalesPerson> salesPeople
<generator class="native"/> Table attribute = new ArrayList();
</id>
specifies the ...
<property name="firstname" />
<property name="lastname" /> join table name
<property name="phoneNr" />
<bag name="salesPeople" table="customer_salesperson">
<key column="customer_id" not-null="true" />
<many-to-many column="salesperson_id" class="SalesPerson" />
</bag>
</class>
</hibernate-mapping> <many-to-many> tag
to map the join table
based relation
public class SalesPerson {
<hibernate-mapping package="manyToMany_uni"> private int id;
<class name="SalesPerson" > private String alias;
<id name="id"> private String phoneNr;
<generator class="native"/>
</id> ...
<property name="alias" />
<property name="phoneNr" />
</class> Regular mapping of
</hibernate-mapping> the SalesPerson class
© 2014 Time2Master 35
Many to Many Bi-directional
@Entity
public class Customer {
@Id
@GeneratedValue
private int id;
private String firstname;
private String lastname; @ManyToMany
private String phoneNr;
@ManyToMany @JoinTable is optional
@JoinTable(name = "Customer_SalesPerson",
joinColumns = { @JoinColumn(name = "Customer_id") },
inverseJoinColumns = { @JoinColumn(name = "SalesPerson_id") }
)
private List<SalesPerson> salesPeople = new ArrayList();

...

Customer SalesPerson
@Entity
called by public class SalesPerson {
+firstname +repId mappedBy
+lastname 0..* 1..* +alias @Id
+phoneNr +phoneNr @GeneratedValue specifies that
+salesPeople +customers
private int id; the other side is
private String alias; the owning side
private String phoneNr;
@ManyToMany(mappedBy="salesPeople")
private List<Customer> customers =
new ArrayList();

...
© 2014 Time2Master 36
Bi-Directional Many to Many XML
public class Customer {
<hibernate-mapping package="manyToMany_bi"> private int id;
<class name="Customer" > private String firstname;
<id name="id"> private String lastname;
<generator class="native"/> private String phoneNr;
</id> private List<SalesPerson> salesPeople
<bag> maps collection = new ArrayList();
<property name="firstname" />
<property name="lastname" /> and specifies table name
<property name="phoneNr" /> ...
<bag name="salesPeople" table="customer_salesperson"> Think of <many-to-many> as
<key column="customer_id" /> the join table mapping tag
<many-to-many column="salesperson_id" class="SalesPerson" />
</bag>
</class>
public class SalesPerson {
</hibernate-mapping>
private int id;
private String alias;
<hibernate-mapping package="manyToMany_bi">
private String phoneNr;
<class name="SalesPerson" >
private List<Customer> customers =
<id name="id">
new ArrayList();
<generator class="native"/>
</id>
...
<property name="alias" />
<property name="phoneNr" />
<bag name="customers" table="customer_salesperson" inverse="true">
Inverse specifies that the
<key column="salesperson_id" /> other side is the owning side
<many-to-many column="customer_id" class="Customer" />
</bag>
</class> Opposite mapping is
</hibernate-mapping> similar, but adds inverse
© 2014 Time2Master 37
Association Mapping

ASSOCIATION CASCADES

© 2014 Time2Master 38
Association Cascades
@Entity @Entity
public class Person { public class Car {
@Id @Id
@GeneratedValue @GeneratedValue
private int id; private int id;
private String firstname; private short year;
private String lastname; private String model;
@OneToMany(mappedBy="owner") private String maker;
private List<Car> cars = @ManyToOne
new ArrayList(); @JoinColumn(name="owner_id")
private Person owner;
...
...

 By default hibernate does not cascade


 During a session.persist(person) its car(s) will not be persisted
 During a session.update(person) its car(s) will not be updated
 During a session.delete(person) its car(s) will not be deleted

© 2014 Time2Master 39
Specifying Cascades
 Each association tag has a cascade attribute
@Entity
public class Person {
@Id
@GeneratedValue Association will cascade
private int id; on Persist operations
private String firstname;
private String lastname;
@OneToMany(mappedBy="owner", cascade=CascadeType.PERSIST)
private List<Car> cars = new ArrayList();
When a person is persisted
... its cars will also be persisted

 Specify an array of cascade types:


@Entity
public class Person {
@Id
@GeneratedValue
private int id; Cascade on persist and Merge
private String firstname;
private String lastname;
@OneToMany(mappedBy="owner", cascade={CascadeType.PERSIST, CascadeType.MERGE})
private List<Car> cars = new ArrayList();

...

© 2014 Time2Master 40
Cascade Types
Hibernate JPA Description
all ALL Cascade on all operations
persist PERSIST Cascade on persist operations
merge MERGE Cascade on merge operations
remove REMOVE Cascade on remove operations
refresh REFRESH Cascade on refresh operations
save-update - Cascade on save or update operations or on flush
delete - Cascade on delete or remove operations
delete-orphan - Cascade into a collection (normal delete doesn’t)
lock - Cascade on lock operations
replicate - Cascade on replicate operations
evict - Cascade on evict operations

© 2014 Time2Master 41
Hibernate Cascade Annotation
 Hibernate annotation extensions can be used
to specify Hibernate specific cascade types
@Entity
public class Person {
@Id
@GeneratedValue
private int id; Cascade on persist and Merge
private String firstname;
private String lastname;
@OneToMany(mappedBy="owner", cascade={CascadeType.PERSIST, CascadeType.MERGE})
@org.hibernate.annotations.Cascade(
org.hibernate.annotations.CascadeType.SAVE_UPDATE
)
private List<Car> cars = new ArrayList();
Cascade on save or update
...

© 2014 Time2Master 42
XML Cascades
<hibernate-mapping package="cascade">
<class name="Car" >
<id name="id">
<generator class="native"/>
</id>
<property name="year" /> Cascade attribute on *-to-one> tags
<property name="model" />
<property name="maker" />
<many-to-one name="owner" column="owner_id" class="Person"
cascade="persist, merge, save-update" />
</class>
</hibernate-mapping>
Any of the Hibernate cascade types

<hibernate-mapping package="cascade">
<class name="Person" >
<id name="id">
<generator class="native"/>
</id> Cascade attribute on collection tags
<property name="firstname" />
<property name="lastname" />
<bag name="cars" inverse="true" cascade="persist, merge, save-update">
<key column="owner_id" />
<one-to-many class="Car"/>
Any of the Hibernate cascade types
</bag>
</class>
</hibernate-mapping>

© 2014 Time2Master 43
Delete Orphan
One to Many without delete-orphan One to Many using delete-orphan
Persistence Persistence
context context

customer customer
Remove a Remove a
creditcard creditcard creditcard creditcard
from the from the
creditcard collection creditcard collection

creditcard creditcard

Persistence Persistence
context context
customer The removed customer
creditcard will The removed
creditcard creditcard creditcard is
be ‘orphaned’
automatically
creditcard deleted from
the database
creditcard creditcard

© 2014 Time2Master 44
Association Mapping

WRAPPING UP

© 2014 Time2Master 45
Mapping Tips
 Reconsider many to many relationships
 Often people want to store additional data related
to many-to-many association
 If not now then perhaps in the near future
 May be better to map the join table as an entity

Customer SalesPerson Customer Call SalesPerson


called by
+firstname +repId +firstname receives +started makes +repId
+lastname 0..* 1..* +alias +lastname +duration +alias
+phoneNr +phoneNr +phoneNr 1 * +subject * 1 +phoneNr
+salesPeople +customers +salesPeople +customers

© 2014 Time2Master 46
Mapping Tips
 One to One relationships are often very tight
 E.g. a Customer always has an Address
 You may want to to include address in the
customer table
 You can do so using embedded classes which we
will explain later in the course
Address
Customer
+street
location
+firstname +suiteOrApt
+lastname +city
+address 1 1
+state
+zip
+customer

© 2014 Time2Master 47
Convenience Methods
 To create or remove a bi-directional association
two references have to be created or removed
 It can become a bit tedious to set both sides
 Create convenience methods that set both
sides in one go
Normal Getter / Setter for the
public class Person { collection of car references

...
public List<Car> getCars() { return cars; }
public void setCars(List<Car> cars) { this.cars = cars; }

public boolean addCar(Car car) {


car.setOwner(this);
return cars.add(car); Convenience
Additional convenience
methods tomethods
set the
} references
to set references
on both
onsides
bothat
sides
once
public boolean removeCar(Car car) {
car.setOwner(null);
return cars.remove(car);
} © 2014 Time2Master 48
Enforced ‘Convenience’
 Don’t allow the collection to be modified
except through convenience methods
 This Ensures that the association is persisted
 Price: Hibernate field access for the collection
public class Person { Getter returns unmodifiable collection
...
public List<Car> getCars() { return Collections.unmodifiableList(cars); }
public void setCars(List<Car> cars) { this.cars = cars; }

public boolean addCar(Car car) {


car.setOwner(this);
Can also remove / omit setter
return cars.add(car);
}
public boolean removeCar(Car car) {
car.setOwner(null); Have to use convenience
return cars.remove(car); methods, the association is
} always persisted

© 2014 Time2Master 49
Active Learning
 What are the seven different types of
associations?

 Why would anyone want to use a join table in


a uni-directional one-to-many association?

© 2014 Time2Master 50
Module Summary
 In this module we discussed how to map the
seven different types of associations
 Both uni-directional and bi-directional associations
 ManyToOne, OneToMany, OneToOne, and ManyToMany
 Most can be mapped in more than one way
 With or without a join table / joining on FKs or PKs
 Association can also specify which actions
should cascade down to the related entities
 Persist, merge, remove, refresh, all

© 2014 Time2Master 51

You might also like