Cascading is like maintaining the state of the Relationship, Cascading is used on the Entity Association Mapping between the tables. It helps the system to maintain the state of the entity, For Example
We have two Entities named Person, Address. Assume both entities mapped together with an association mapping. Now when we do a DELETE operation in the main Entity Person, the data is also to be deleted, because Address is no longer needed without a person. This deletion on the Address Entity happens based on the Cascading Configuration on the Main Entity Person.
Simply we call, Child Entity do the same what Parent Entity do.
Example :
@OneToMany(cascade=MERGE, mappedBy="person")
Cascading Types :
Cascading Operations have many Types in them.
ALL: This means the Cascading defined in all levels, Whatever the action happens will get reflected in Child Entity
DETACH: When the parent Entity DETACH from the Persistence state, the Child Entity also get detached
MERGE: When the parent Entity MERGE from the Persistence state, the Child Entity also get merged
PERSIST: When the parent Entity PERSIST from the Persistence state, the Child Entity also get persisted
REFRESH: When the parent Entity REFRESH in the Persistence state, the Child Entity also get refreshed
REMOVE: When the parent Entity REMOVE from the Persistence state, the Child Entity also get removed
In addition to that, Hibernate supports additional Cascading Types such as SAVE_UPDATE, REPLICATE, LOCK
The below example shows to configure the Cascading type in Entity Mapping Associations
Example :
EmployeeEntityTest.java
@Entity @Table(name = "Employee_Test") public class EmployeeEntityTest { @OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumn private AccountEntityTest account; public Integer getEmployeeId() { return employeeId; } public void setEmployeeId(Integer employeeId) { this.employeeId = employeeId; } }
AccountEntityTest.java
@Entity @Table(name = "ACCOUNT_TEST") public class AccountEntityTest { @Column(name = "ACC_NUMBER", unique = true, nullable = false, length = 100) private String accountNumber; }
In the above example, Cascade Type is mentioned in the EmployeeEntityTest Class as well as AccountEntityTest, This is because we have used OneToOne and it can be bi-directional mapping.
Now let us see the cascading type one by one with an example.
Cascade Type ALL is the default setup, It means all the Repository operations are accepted, look at the below example
@OneToOne(cascade = CascadeType.MERGE) @PrimaryKeyJoinColumn private AccountEntityTest account;
In the above we have defined the Cascading Type as MERGE, Hence update and insert supported. Now if the user tries to delete the record using any one delete() method, the records won’t get deleted, Because we have defined the cascading at merge level. So when we invoke the Delete operation as follows,
//Delete Record this.deleteEmployeeTestById(41);
public void deleteEmployeeTestById(int id) throws Exception { Optional<EmployeeEntityTest> employee = testrepository.findById(id); if(employee.isPresent()) { testrepository.deleteById(id); } else { throw new Exception("No employee Test available to Delete"); } Logging.info("Employee Record Deleted "); }
The above method will get executed properly, But the record won’t get deleted in the Database and you will not find the deletion in Output.
Now if you change the Cascade Type to ALL. All the operations including deletion you can seen in the output. The delete operation will get executed as expected.
Hibernate: select hibernate_sequence.nextval from dual Hibernate: insert into account_test (acc_number, id) values (?, ?) Hibernate: insert into employee_test (email, first_name, last_name, id) values (?, ?, ?, ?) 2022-01-05T00:56:21.918+0530 INFO Employee Record Before Insertion Test3 : Hibernate: select employeeen0_.id as id1_4_0_, employeeen0_.email as email2_4_0_, employeeen0_.first_name as first_name3_4_0_, employeeen0_.last_name as last_name4_4_0_ from employee_test employeeen0_ where employeeen0_.id=? Hibernate: select accountent0_.id as id1_0_0_, accountent0_.acc_number as acc_number2_0_0_, employeeen1_.id as id1_4_1_, employeeen1_.email as email2_4_1_, employeeen1_.first_name as first_name3_4_1_, employeeen1_.last_name as last_name4_4_1_ from account_test accountent0_ inner join employee_test employeeen1_ on accountent0_.id=employeeen1_.id where accountent0_.id=? Hibernate: delete from employee_test where id=? Hibernate: delete from account_test where id=? 2022-01-05T00:56:22.029+0530 INFO Employee Record Deleted Test :
Conclusion :
In this article, we have gone through the Cascading Types in JPA and learned to use them with Spring Boot.
Happy Learning .!!