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(), ….
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
Type | Description |
---|---|
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
Type | Description |
---|---|
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);
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.