简体   繁体   中英

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!

Look at orphanRemoval option:

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

Here is complete explication about CascadeType.REMOVE and orphanRemoval .

Good luck!

Relationships in JPA are always unidirectional , unless you associate the parent with the child in both directions. Cascading REMOVE operations from the parent to the child will require a relation from the parent to the child (not just the opposite).

So here you need to change unidirectional relationship to bi-directional.

for more details refer this link.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM