我有一个实体类,其中每个实例都可以拥有相同类型的父类。
现在我希望能够删除父对象,并在此过程中删除所有子对象。我无法通过级联类型执行此操作,因此我在JPA存储库中创建了自定义查询。不幸的是,由于自定义查询存在某种错误,因此无法创建此bean。
实体类
@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;
}
存储库界面
@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());
}
}
}
}
如我所见,我想通过deleteBericht
方法从层次结构的底部开始删除,并在层次结构中向上工作到顶部。
有没有比上面显示的deleteBericht
方法更好的解决方案?
答案 0 :(得分:0)
首先要尽量避免反复,总是冒险。
我为您提供了另一个解决方案,获取所有kind.id
的列表,然后像Query s = entytiManager.createQuery("Delete * From KindTable k Where k.id In ( :kIdLst )");
那样进行SQL删除,并通过q.setList("kIdLst", kindIds);
提供kIdLst
答案 1 :(得分:0)
首先,您的基本映射存在一些问题。如果它是实体,则它不应该有@Embeddable
注释。此外,您不应该@Transactional
上有@Entity
。
无论如何,我希望你能够以正常方式删除,如果你要将关系双向化,如下所示:
@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;
}
}
现在删除Bericht实例时,应自动删除任何子项。
Bericht b = //some Bericht
berichtRepository.delete(b);// should cascade down through all children