Java JpaRepository @Query加入自己的表

时间:2016-10-04 16:02:53

标签: java spring hibernate spring-data-jpa

我有一个实体类,其中每个实例都可以拥有相同类型的父类。

现在我希望能够删除父对象,并在此过程中删除所有子对象。我无法通过级联类型执行此操作,因此我在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方法更好的解决方案?

2 个答案:

答案 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