Delete-orphan with Cascade
Let’s perform Delete Orphan operation with and without cascade to understand it better
delete-orphan with Cascade
Orphan record is a record in relation table which doesn’t have any association with its relationship owner.
Example:Applicant has a list of address, suppose we delete this address list association with Applicant then all the address records becomes Orphan records.
Such orphan records can be deleted automatically whenever the Association is removed using Cascade
Annotation configuration
Applicant.java
- @OneToMany(mappedBy="applicant")
- @Cascade(CascadeType.DELETE_ORPHAN)
- private Set<Address> addresses;
@OneToMany(mappedBy="applicant") @Cascade(CascadeType.DELETE_ORPHAN) private Set<Address> addresses;
Note:If we use JPA 2.0, we can use the orphanRemoval=true attribute of the @xxxToManyannotation to remove orphans.
Actually, CascadeType.DELETE_ORPHAN has been deprecated in 3.5.2-Final.
XML configuration
applicant.hbm.xml
- <set name="addresses" table="Address"
- inverse="true" lazy="true" fetch="select" cascade="delete-orphan">
- <key>
- <column name="Applicant_Id" not-null="true" />
- </key>
- <one-to-many class="Address" />
- </set>
<set name="addresses" table="Address" inverse="true" lazy="true" fetch="select" cascade="delete-orphan"> <key> <column name="Applicant_Id" not-null="true" /> </key> <one-to-many class="Address" /> </set>
Example to Delete Orphan records
- Applicant applicant = session.get(Applicant.class, 1);
- Address address1 = session.get(Address.class, 2);
- Address address2 = session.get(Address.class, 3);
- applicant.getAddresses().remove(address1);
- applicant.getAddresses().remove(address2);
- session.update(applicant);
Applicant applicant = session.get(Applicant.class, 1); Address address1 = session.get(Address.class, 2); Address address2 = session.get(Address.class, 3); applicant.getAddresses().remove(address1); applicant.getAddresses().remove(address2); session.update(applicant);
Output Queries generated
delete from Address where Address_Id=? Hibernate: delete from Address where Address_Id=?
We can see that all the Address records are deleted when we removed address objects from the Applicant address list.
When we removed address objects from Applicant’s address list , they become Orphan but still present in DB.
Since we used Cascade for Delete orphan, these address orphan records also gets removed from DB.
Output in DB
delete-orphan without Cascade
If we don’t use Cascade with Delete Orphan scenario as explained above, we end up with having orphan records in the DB and we must explictely delete them as well.
We need to delete each address record one by one.
Annotation configuration
Applicant.java
- @OneToMany(mappedBy="applicant")
- private Set<Address> addresses;
@OneToMany(mappedBy="applicant") private Set<Address> addresses;
XML configuration
applicant.hbm.xml
- <set name="addresses" table="Address"
- inverse="true" lazy="true" fetch="select">
- <key>
- <column name="Applicant_Id" not-null="true" />
- </key>
- <one-to-many class="Address" />
- </set>
<set name="addresses" table="Address" inverse="true" lazy="true" fetch="select"> <key> <column name="Applicant_Id" not-null="true" /> </key> <one-to-many class="Address" /> </set>
Example to delete Orphan Address records explicitly without Cascade
- Address address1 = session.get(Address.class, 2);
- Address address2 = session.get(Address.class, 3);
- session.delete(address1);
- session.delete(address2);
Address address1 = session.get(Address.class, 2); Address address2 = session.get(Address.class, 3); session.delete(address1); session.delete(address2);
Output Queries generated
Hibernate: delete from Address where Address_Id=? Hibernate: delete from Address where Address_Id=?
Since we are not using Cascade with Delete Orphan, We have deleted each address record one by one.
If we use Cascade then we don’t need to delete them one by one, we just need to remove them from the Address collection of Applicant and updating the Applicant will take care of deleting these Orphan records automatically.
Output in DB