Cascading

Cascading means that if you insert, update or delete an object, related objects are inserted, updated or deleted as well. If you do not use cascade you would have to save both objects independently. If you initially create objects and you do not cascade then you must save each object explicitly.

Department d = new Department();
Team t1 = new Team();
Team t2 = new Team();
d.getTeams().add(t1);
d.getTeams().add(t2);
t1.setDepartment(d);
t2.setDepartment(d);
session.save(d);
session.save(t1);
session.save(t1);

If you configure cascade on the department side

Annotation. 

@OneToMany(cascade = {CascadeType.ALL})
private Set<Team> teams;

XML. 

<set name="teams" table="tteam" inverse="false" cascade="all">
  <key column="department_id"></key>
  <one-to-many class="Team"/>
</set>

then you only need to call

session.save(d);

and the rest will be automatically cascaded. You can combine options, as well.

JPA Standard Annotation. 

@OneToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST})

Hibernate Annotation. 

@OneToMany
@Cascade({CascadeType.MERGE, CascadeType.PERSIST})

XML. 

<set name="teams" table="tteam" inverse="false"
  cascade="persist,lock,replicate,save-update,delete,delete-orphan,refresh">

The following tables explains the different cascade types available. You will see that they are linked to methods from the session like session.persist(), session.delete(), session.buildLockRequest(LockOptions.NONE).lock(), ….

Note

Java Persistence and Hibernate provides both a way to configure cascading. If you use the Hibernate API (the session), then I recommend to use @Cascade(…). If you use the Java Persistence API (EntityManager), then you should use the cascading options inside of the relation @OneToMany(cascade = {…}). The simple reason: the JPA misses options to cascade session API methods like save, update or replicate.

Table 7.2. JPA Annotation Cascade Types

TypeDescription

ALL

Cascades all but not the deletion of orphan members.

PERSIST

session.persist()

MERGE

session.merge()

REMOVE

session.delete(), does not delete orphan members

REFRESH

session.refresh() rereads object from the datbase (useful after trigger execution)


Table 7.3. Hibernate Annotation and XML cascade types

TypeDescription

none

Default style, do not cascade

all

Cascades all but not the deletion of orphan members.

all-delete-orphan

All + delete-orphan

persist

session.persist()

save-update

session.saveOrUpdate()

save()

update()

lock

session.buildLockRequest(LockOptions.NONE).lock()

delete

Session.delete()

does not delete orphan members

delete-orphan

Deprecated, Deletes orphan members, for example you delete the department and the teams must be deleted as well.

refresh

session.refresh() rereads object from the database (useful after trigger execution)

evict or detach

Session.evict() removes an object from the session cache

replicate


Orphan Removal

If you remove for example an invoice position from the collection of an invoice, it is called an orphan entit. If you configure orphan removal it will be deleted just by fact that it was removed from the collection.

Since Java Persistence 2.0 orphan removal, the Hibernate cascade type is deprecated. Here is the correct way to use it.

@OneToMany (cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<InvoicePosition> positions;

Usage. 

Invoice invoice = (Invoice) session.get(Invoice.class, 4711);
invoice.getPositions().remove(1);

Understanding the examples

You can find the source code for annotation mapping in the mapping-examples-annotation project. The sourcecode of the XML mappings is in the mapping-examples-xml project. Each example references a package in the provided source code. We will explain the relevant part of the mapping, resulting tables and some more information in the book. You can find classes and a test class showing examples how to insert, update, delete and query the mapped objects in the source code.