Reputation: 67
I have two classes Parent
and Child
with one to many relation.
Lets suppose that I have already persisted in my database structure like this:
Parent--> Child1, Child2
And than I get this new structure (with changes in Child1
, without Child2
and with new Child3
):
Parent--> Child1, Child3
So: Child1
should be updated, Child2
should be removed and Child3
should be added.
Unfortunately Hibernate with CasadeType.ALL
and orphanRemoval=true
only adds and updates, but don't delete automatically Child2
. I need to compare list with entites to update and persisted one to look for objects to delete.
I wonder if there is any pattern that solves in elegant way my problem or maybe should I change some properties in Hibernate?
--- EDIT ---
Entities aren't anything fancy, something like this lets say:
@Entity
@Data
public class Parent {
@Id
@GeneratedValue(strategy = SEQUENCE)
private long id;
@OneToMany(mappedBy = "parent", casade = CasadeType.ALL, orphanRemoval = true)
private Set<Child> childList;
}
@Entity
@Data
public class Child {
@Id
@GeneratedValue(strategy = SEQUENCE)
private long id;
@ManyToOne
@JoinColumn(name = "xxx")
private Parent parent;
}
Upvotes: 2
Views: 2122
Reputation: 1259
This is the pattern I follow:
@Entity
@Data
public class Parent {
@Id
@GeneratedValue(strategy = SEQUENCE)
private long id;
@OneToMany(mappedBy = "parent", casade = CasadeType.ALL, orphanRemoval = true)
private Set<Child> childList = new HashSet<>();
public void addChild(Child child){
if(child!=null){
this.childList.add(child);
child.setParent(this);
}
}
public void removeChild(Child child){
if(child!=null){
this.childList.remove(child);
child.setParent(null);
}
}
public void updateChildren(Collection<Child> children){
childList.forEach(x-> if(!children.contains(x)) this.removeChild(x); );
children.forEach(x-> this.addChild(x));
}
}
EDIT
You can create generic classes like this and use it. NOTE: THIS IS WAY COMPLEX TO IMPLEMENT
@MappedSuperClass
@Data
class Child<P extends Parent,C extends Child>{
Parent<P,C> parent ;
}
@MappedSuperClass
@Data
class Parent<P extends Parent,C extends Child>{
@Id
@GeneratedValue(strategy = SEQUENCE)
private long id;
@OneToMany(mappedBy = "parent", casade = CasadeType.ALL, orphanRemoval = true)
private Set<C> childList = new HashSet<>();
public void addChild(C child){
if(child!=null){
this.childList.add(child);
child.setParent(this);
}
}
public void removeChild(C child){
if(child!=null){
this.childList.remove(child);
child.setParent(null);
}
}
public void updateChildren(Collection<C> children){
childList.forEach(x-> {if(!children.contains(x)) this.removeChild(x); });
children.forEach(this::addChild);
}
}
Upvotes: 2