Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete child from parent and parent from child automatically with JPA annotations

Suppose that we have 3 Entities object class:

class Parent {
    String name;
    List<Child> children;
}

class Child {
    String name;
    Parent parent;
}

class Toy {
    String name;
    Child child;
}

How can I use JPA2.x (or hibernate) annotations to:

  1. Delete all children automatically when parent delete (one to many)
  2. Delete child automatically from children list when it is deleted (many to one)
  3. Delete toy automatically when child remove (one to one)

I'm using Hibernate 4.3.5 and mysql 5.1.30.

Thanks

like image 500
user1079877 Avatar asked May 29 '14 03:05

user1079877


People also ask

How do you delete child records when parent is deleted in hibernate?

The correct way is to create the foreign key on mail to reference account . With ON DELETE CASCADE , you tell MySQL that it should delete a row (whose table has the foreign key) if its parent (referenced by the key) is deleted.

How do you delete a one to many relationship in JPA?

If an entity that is the target of the relationship is removed from the relationship (by setting the relationship to null or removing the entity from the relationship collection), the remove operation will be applied to the entity being orphaned. The remove operation is applied at the time of the flush operation.


3 Answers

The remove entity state transition should cascade from parent to children, not the other way around.

You need something like this:

class Parent {

    String name;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    List<Child> children = new ArrayList<>();

    public void addChild(Child child) {
        child.setParent(this);
        children.add(child);
    }

    public void removeChild(Child child) {
        children.remove(child);
        child.setParent(null);
    }
}

class Child {

    String name;

    @ManyToOne
    Parent parent;
    
    @OneToOne(mappedBy = "child", cascade = CascadeType.ALL, orphanRemoval = true)
    Toy toy;
}

class Toy {
    String name;

    @OneToOne
    Child child;
}
like image 197
Vlad Mihalcea Avatar answered Sep 20 '22 13:09

Vlad Mihalcea


You should use CascadeType.REMOVE. This is common annotation for both Hibernate and JPA. Hibernate has another similar type CacadeType like CascadeType.DELETE.

  1. Delete all children automatically when parent delete (one to many)

    class Parent {
      String name;
    
      @OneToMany(cascade = CascadeType.REMOVE)
      List<Child> children;
    }
    
  2. Delete child automatically from children list when it is deleted (many to one)

    class Child {
     String name;
     @ManyToOne(cascade = CascadeType.REMOVE)
     Parent parent;
    }
    
  3. Delete toy automatically when child remove (one to one)

    class Toy {
      String name;
      @OneToOne(cascade = CascadeType.REMOVE)
      Child child;
    }
    
like image 37
Masudul Avatar answered Sep 16 '22 13:09

Masudul


orphanRemoval is delete all orphan entity example: store (s) has books(b1,b2,b3) and b1 has title(t) in this case if deleted store(s) some books(b2,b3) will be deleted. B2 and t still exist. if you use "cascade= CascadeType.Remove" just store(s) and all books will be deleted (only "t" exist).

s->b1,b2,b3 b2->t ------after(orphanRemoval = true)--------- b2->t

s->b1,b2,b3 b2->t ------ after(cascade=CascadeType.REMOVE)--------- t

If orphanRemoval=true is specified the disconnected entity instance is automatically removed. This is useful for cleaning up dependent objects that should not exist without a reference from an owner object.

If only cascade=CascadeType.REMOVE is specified no automatic action is taken since disconnecting a relationship is not a remove operation.

like image 31
Adiya Buyantogtokh Avatar answered Sep 16 '22 13:09

Adiya Buyantogtokh