I have an entity class where each instance can have a parent of the same type.
Now I want to be able to delete a parent object, and in the process delete all its children with it. I couldn't do it via a cascade type so I made a custom query in my JPA repository. Unfortunately this bean could not be created because the custom query has some kind of error.
Entity class
@Entity
@Transactional
@Table(name = "bericht")
@Proxy(lazy = false)
@Embeddable
public class Bericht implements Serializable {
@Id
@GeneratedValue
private Integer id;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.DETACH)
@JoinColumn(name = "PARENT_ID")
private Bericht parent;
}
Repository interface
@Transactional
public interface BerichtRepository extends JpaRepository<Bericht, Integer> {
@Query("SELECT b1 FROM Bericht b join Bericht b1 WHERE b1.parent.id <> NULL AND b1.parent.id = b.id AND b.id = ?1 order by b1.id desc")
public List<Bericht> getChildrenVanBericht(Integer id);
public default void deleteBericht(Integer id) {
List<Bericht> kinderen = getChildrenVanBericht(id);
for(Bericht kind:kinderen) {
if(getChildrenVanBericht(kind.getId()).size()==0) {
this.delete(kind);
} else {
deleteBericht(kind.getId());
}
}
}
}
As seen I want to start deleting from the bottom of the hierarchy via the deleteBericht
method and work upwards in the hierarchy to the top.
Is there a better solution out there than the deleteBericht
method as shown above?
First of all try to avoid recurcivity, it's always risky.
I purpose you an other solution, get the list of all the kind.id
then make an SQL delete like Query s = entytiManager.createQuery("Delete * From KindTable k Where k.id In ( :kIdLst )");
and provide kIdLst through q.setList("kIdLst", kindIds);
Good luck ! Z
Firstly you have some problems with your basic mapping. If it's an Entity it shouldn't have the @Embeddable
annotation. Additionally, you shouldn't have @Transactional
on an @Entity
.
Anyway, I would expect that you should be able to delete in the normal way if you were to make the relationship bi-directional as below:
@Entity
@Table(name = "bericht")
@Proxy(lazy = false)
public class Bericht implements Serializable {
@OneToOne(mappedBy = "parent", cascade = CascadeType.DELETE)
private Bericht child;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.DETACH)
@JoinColumn(name = "PARENT_ID")
private Bericht parent;
//additionally always ensure both sides of the relationship are consistent
public void setChild(Bericht child){
this.child = child;
child.parent = this;
}
public void setParent(Bericht parent){
this.parent = parent;
parent.child = this;
}
}
Now when deleting a Bericht instance any children should be deleted automatically.
Bericht b = //some Bericht
berichtRepository.delete(b);// should cascade down through all children
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.