Hibernate Cascade All Save Update Delete And Delete Orphan
In hibernate we model the parent and child relationship and usually two approaches are available to achieve it. Most simple approach is to model both Parent and Child class with One-To-Many relation from Parent to Child. Alternative approach is declaring Child as Composite-element. In this tutorial we will see how to use bi-directional One-To-Many association using cascades from parent to child relationship efficiently.
We will discuss below cascade types:
- None (Default)
- CascadeType.ALL
- CascadeType.SAVE_UPDATE
- CascadeType.DELETE
- CascadeType.DELETE_ORPHAN
Note: Please go through our previous Hibernate One To Many Annotation Example tutorial and here we will use partial code to show cascade type example
1. None (Default) : If you do not define cascade type then default cascade will be none and you will have to save all data explicitly as shown below:
- Annotation based configuration cascade not defined:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "mother") public Set<Child> getChilds() { return this.childs; }
- XML based configuration cascade not defined:
<set name="childs" table="child" inverse="true" lazy="true" fetch="select"> <key> <column name="mother_id" /> </key> <one-to-many class="com.javahonk.bean.Child" /> </set>
- Java class example cascade not defined:
Mother mother=new Mother(); mother.setFirstName("Mary"); mother.setLastName("Kay"); mother.setCity("Edison"); mother.setZip("10038"); mother.setState("NJ"); //Saving mother data session.save(mother); Child child=new Child(); child.setFirstName("Tom"); child.setLastName("Kay"); child.setMother(mother); //Saving child data session.save(child); Child child2=new Child(); child2.setFirstName("John"); child2.setLastName("Kay"); child2.setMother(mother); //Saving child data session.save(child2);
Output:
2. CascadeType.ALL : It means is that when persistence (Persisting parent) happens it will propagate (cascade) all Entity Manager related operations (Merge, Remove, PERSISTREFRESH, DETACH) to relating entities (Child entity) and in another words all operations will be cascaded along with association.
- Annotation based configuration CascadeType.ALL:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "mother") @Cascade({CascadeType.ALL}) public Set<Child> getChilds() { return this.childs; }
- XML based configuration CascadeType.ALL:
<set name="childs" table="child" inverse="true" lazy="true" fetch="select" cascade="all"> <key> <column name="mother_id" /> </key> <one-to-many class="com.javahonk.bean.Child" /> </set>
- Java class example CascadeType.ALL:
Mother mother=new Mother(); mother.setFirstName("Mary"); mother.setLastName("Kay"); mother.setCity("Edison"); mother.setZip("10038"); mother.setState("NJ"); Child child=new Child(); child.setFirstName("Tom"); child.setLastName("Kay"); child.setMother(mother); Child child2=new Child(); child2.setFirstName("John"); child2.setLastName("Kay"); child2.setMother(mother); Set<Child> childsSet = new HashSet<Child>(); childsSet.add(child); childsSet.add(child2); mother.setChilds(childsSet); session.save(mother);
Output:
3. CascadeType.SAVE_UPDATE: This cascade type applies during save or update operation against the database:
- Annotation based configuration CascadeType.SAVE_UPDATE:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "mother") @Cascade({CascadeType.SAVE_UPDATE}) public Set<Child> getChilds() { return this.childs; }
- XML based configuration CascadeType.SAVE_UPDATE:
<set name="childs" table="child" inverse="true" lazy="true" fetch="select" cascade="save-update"> <key> <column name="mother_id" /> </key> <one-to-many class="com.javahonk.bean.Child" /> </set>
- Java class example CascadeType.SAVE_UPDATE:
Mother mother=new Mother(); mother.setFirstName("Mary"); mother.setLastName("Kay"); mother.setCity("Edison"); mother.setZip("10038"); mother.setState("NJ"); Child child=new Child(); child.setFirstName("Tom"); child.setLastName("Kay"); child.setMother(mother); Child child2=new Child(); child2.setFirstName("John"); child2.setLastName("Kay"); child2.setMother(mother); session.save(child2); Set<Child> childsSet = new HashSet<Child>(); childsSet.add(child); childsSet.add(child2); mother.setChilds(childsSet); session.save(mother);
Output:
4. CascadeType.DELETE: This cascade type applies when delete operation performs against the database:
- If no delete cascade defined then you will have to delete data when looping through the object as shown below java code:
Session session = sf.openSession(); session.beginTransaction(); List<Mother> moList = session.createQuery("from Mother where" + " motherId = 1").list(); for (Mother mother2 : moList) { Set<Child> childs=mother2.getChilds(); for (Iterator<Child> iterator = childs.iterator(); iterator.hasNext();) { Child child3 = (Child) iterator.next(); session.delete(child3); } session.delete(mother2); } session.getTransaction().commit(); session.close();
Delete defined:
- Annotation based configuration CascadeType.DELETE defined:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "mother") @Cascade({CascadeType.DELETE}) public Set<Child> getChilds() { return this.childs; }
- XML based configuration CascadeType.DELETE defined:
<set name="childs" table="child" inverse="true" lazy="true" fetch="select" cascade="delete"> <key> <column name="mother_id" /> </key> <one-to-many class="com.javahonk.bean.Child" /> </set>
- Java class example CascadeType.DELETE defined:
Session session = sf.openSession(); session.beginTransaction(); List<Mother> moList = session.createQuery("from Mother where" + " motherId = 2").list(); for (Mother mother2 : moList) { session.delete(mother2); } session.getTransaction().commit(); session.close();
Output:
5. CascadeType.DELETE_ORPHAN:
- If no DELETE_ORPHAN cascade defined then you will have to delete data one by one as shown java code below:
Session session = sf.openSession(); session.beginTransaction(); Child child = (Child)session.get(Child.class,new Integer(5)); Child child2 = (Child)session.get(Child.class,new Integer(6)); session.delete(child); session.delete(child2); session.getTransaction().commit(); session.close();
DELETE_ORPHAN defined:
- Annotation based configuration CascadeType.DELETE_ORPHAN defined:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "mother") @Cascade({CascadeType.DELETE_ORPHAN}) public Set<Child> getChilds() { return this.childs; }
- XML based configuration CascadeType.DELETE_ORPHAN defined:
<set name="childs" table="child" inverse="true" lazy="true" fetch="select" cascade="delete-orphan"> <key> <column name="mother_id" /> </key> <one-to-many class="com.javahonk.bean.Child" /> </set>
- Java class example CascadeType.DELETE_ORPHAN defined:
Session session = sf.openSession(); session.beginTransaction(); Child child = (Child)session.get(Child.class,new Integer(9)); Child child2 = (Child)session.get(Child.class,new Integer(10)); Mother mother = (Mother)session.get(Mother.class,new Integer(7)); mother.getChilds().remove(child); mother.getChilds().remove(child2); session.saveOrUpdate(mother); session.getTransaction().commit(); session.close();
That’s it Hibernate Cascade All Save Update Delete And Delete Orphan for more information please read this hibernate tutorial