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

1
2
3
4
5
@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

1
2
3
4
5
6
7
<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

1
2
3
4
5
6
7
8
9
10
11
        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

cascade-delete-orphan

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

1
2
3
@OneToMany(mappedBy="applicant")
 
    private Set<Address> addresses;
@OneToMany(mappedBy="applicant")

    private Set<Address> addresses;

XML configuration

applicant.hbm.xml

1
2
3
4
5
6
7
<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

1
2
3
4
5
6
7
            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

cascade-delete-orphan

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on