JPA / Hibernate Cascade Types - CascadeType.REMOVE

In this post, we will discuss the usage of JPA CascadeType.REMOVE with an example.

Cascading is the way to achieve this. When we perform some action on the target entity, the same action will be applied to the associated entity.

JPA Cascade Types:

All JPA-specific cascade operations are represented by the javax.persistence.CascadeType enum containing entries:

  • ALL - cascades all entity state transitions
  • PERSIST - cascades the entity persist operation.
  • MERGE - cascades the entity merge operation.
  • REMOVE - cascades the entity to remove operation.
  • REFRESH - cascades the entity refresh operation.
  • DETACH - cascades the entity detach operation.

Hibernate Cascade Types:

Hibernate supports three additional Cascade Types along with those specified by JPA. These Hibernate-specific Cascade Types are available in org.hibernate.annotations.CascadeType:
  • SAVE_UPDATE - cascades the entity saveOrUpdate operation.
  • REPLICATE - cascades the entity replicate operation.
  • LOCK - cascades the entity lock operation.

CascadeType.REMOVE Example

As the name suggests, the remove operation removes the row corresponding to the entity from the database and also from the persistent context.

CascadeType.REMOVE propagates the removal operation from parent to child entity. Similar to JPA's CascadeType.REMOVE, we have CascadeType.DELETE, which is specific to Hibernate. There is no difference between the two.

Consider we have Person and Address JPA entities:

Person.java

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    @OneToMany(mappedBy = "person", cascade = CascadeType.REMOVE)
    private List<Address> addresses;
    // getters and setters
}

Address.java

@Entity
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String street;
    private int houseNumber;
    private String city;
    private int zipCode;
    @ManyToOne(fetch = FetchType.LAZY)
    private Person person;
   
    // getter and setter methods
}

CascadeType.REMOVE Example

The below snippet propagates the removal operation from parent to child entity:

Person person = new Person();
person.setName("Admin");

Address address = new Address();
address.setCity("Mumbai");
address.setHouseNumber(23);
address.setStreet("Rural");
address.setZipCode(123456);
address.setPerson(person);

person.setAddresses(Arrays.asList(address));
session.persist(person);
session.flush();
personId = person.getId();
session.clear();

Person savedPersonEntity = session.find(Person.class, personId);
session.remove(savedPersonEntity);
session.flush();

When we run the above test case, we'll see the following SQL:

Hibernate: delete from Address where id=?
Hibernate: delete from Person where id=?

The address associated with the person also got removed as a result of CascadeType REMOVE.

References


Comments