user1079877
user1079877

Reputation: 9368

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

Upvotes: 23

Views: 74260

Answers (3)

Vlad Mihalcea
Vlad Mihalcea

Reputation: 153810

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;
}

Upvotes: 36

Adiya Buyantogtokh
Adiya Buyantogtokh

Reputation: 171

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.

Upvotes: 1

Masudul
Masudul

Reputation: 21971

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;
    }
    

Upvotes: 10

Related Questions