Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA + Hibernate + Spring + OneToMany delete cascade

I've read some related questions but they are not exactly the same problem as mine.

I'm using JPA + Hibernate + Spring and I want to do something that I'm not sure if it is possible just with config.

I have my domain classes with a more or less complicated relation. There are many elements that are related with one element (like if it was a tree many elements are sons of one element).

Something like:

@Entity class Foo {     @Id     @GeneratedValue(strategy = GenerationType.IDENTITY)     private Integer id;      @ManyToOne     @JoinColumn(name = "PARENT_ID")     private Foo parentNode;     ... } 

Which will get a table like:

Foo id    parent_id 1 2         1  3         1 

When I delete row with id = 1 I want to delete rows with id = 2 and id = 3 (it may be recursive, elements with parent_id = 2 and parent_id = 3 would be deleted as well).

For some restrictions I only can have the relation in son's side with the parent_id reference.

My question is: is it possible to do this with JPA or Hibernate configuration or do I need to do some recursive function to delete all children and all parents?

I've tried with:

@OneToMany(name = "PARENT_ID", cascade = CascadeType.REMOVE) 

And I've read that maybe using Hibernate annotations.

If anyone can give me some clue I'm lost at this point.

Edit 1

Would it be possible to do like:

@Entity class Foo {     @Id     @GeneratedValue(strategy = GenerationType.IDENTITY)     private Integer id;      @ManyToOne     @JoinColumn(name="PARENT_ID")     private Foo parentNode;      @OneToMany(fetch = FetchType.LAZY, mappedBy = "parentNode", cascade = CascadeType.REMOVE, orphanRemoval = true)     private Set<Foo> childs = new LinkedHashSet<Foo>();     ... } 

Keeping the table as is, with the fk to the parent? I've tried this but I keep getting the same error, fk restriction violated.

Edit 2

Finally solved with:

@Entity class Foo {     @Id     @GeneratedValue(strategy = GenerationType.IDENTITY)     private Integer id;      @ManyToOne     @JoinColumn(name = "PARENT_ID")     private Foo parentNode;      @OneToMany(mappedBy = "parentNode", cascade = CascadeType.REMOVE)     private Set<Foo> childs = new LinkedHashSet<Foo>();     ... } 

This @OneToMany is needed even if we do the mapping in our BBDD by refering just the parent id.

Now when we delete a Foo with childs, it's childs will be deleted as well.

Thanks for your time and good advices!

like image 753
Garci García Avatar asked Sep 22 '14 06:09

Garci García


People also ask

How do I get rid of Cascade JPA?

First, we'll start with CascadeType. REMOVE which is a way to delete a child entity or entities when the deletion of its parent happens. Then we'll take a look at the orphanRemoval attribute, which was introduced in JPA 2.0. This provides us with a way to delete orphaned entities from the database.

Is orphanRemoval true?

For example, if an order has many line items and one of them is removed from the order, the removed line item is considered an orphan. If orphanRemoval is set to true, the line item entity will be deleted when the line item is removed from the order.

How do I delete a record using JPA?

We can use the JPA method deleteById() for deleting the record of the particular primary key.


1 Answers

Look at orphanRemoval option:

@OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true) 

Here is complete explication about CascadeType.REMOVE and orphanRemoval.

Good luck!

like image 112
jmvivo Avatar answered Sep 23 '22 01:09

jmvivo