简体   繁体   English

Java JpaRepository @Query连接自己的表

[英]Java JpaRepository @Query join own table

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. 我无法通过级联类型执行此操作,因此我在JPA存储库中进行了自定义查询。 Unfortunately this bean could not be created because the custom query has some kind of error. 不幸的是,由于自定义查询存在某种错误,因此无法创建该bean。

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. 如所见,我想通过deleteBericht方法从层次结构的底部开始删除,并在层次结构中向上移动至顶部。

Is there a better solution out there than the deleteBericht method as shown above? 有没有比上面显示的deleteBericht方法更好的解决方案?

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 )"); kind.id给您另一个解决方案,获取所有kind.id的列表,然后进行SQL删除,例如Query s = entytiManager.createQuery("Delete * From KindTable k Where k.id In ( :kIdLst )"); and provide kIdLst through q.setList("kIdLst", kindIds); 并通过q.setList("kIdLst", kindIds);提供kIdLst 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. 如果是实体,则不应具有@Embeddable批注。 Additionally, you shouldn't have @Transactional on an @Entity . 另外,您不应该在@Entity上使用@Transactional

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实例时,应自动删除所有子级。

Bericht b = //some Bericht
berichtRepository.delete(b);// should cascade down through all children

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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