简体   繁体   English

从父级JPA中获取所有子级和子级

[英]Getting all children and subchildren from parent JPA

I have a table TABLE that can have parents of the same type. 我有一个表TABLE,可以有相同类型的父母。 In Java the child can reach the parent but the parent doesn't have a list of children. 在Java中,子级可以到达父级,但是父级没有子级列表。

In MySQL I was able to create the following query that gives me the children and subchildren of the parent, but I'm unable to translate this into JPA Java. 在MySQL中,我能够创建以下查询,该查询为我提供了父级的子级和子级子,但是我无法将其转换为JPA Java。

How can I translate this query: 如何翻译此查询:

SELECT * 
FROM TABLE AS T1 
INNER JOIN 
  (SELECT id FROM TABLE WHERE TABLE.parentId = 966) AS T2 
  ON T2.id = T1.parentId OR T1.parentId = 966 
GROUP BY T1.id

Into java language, using Criteria builder and Criteria Query, I already tried something like this: 使用标准构建器和标准查询进入Java语言,我已经尝试过类似的方法:

CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<TABLE> cq = cb.createQuery(TABLE.class);
    Root<TABLE> tABLE= cq.from(TABLE.class);

    Predicate result = cb.conjunction();

    Join<TABLE, TABLE> TABLEJoin = tABLE.join("parent", JoinType.INNER);
    result = cb.and(result, cb.equal(genericLocationJoin.get("parent"), location));
em.createQuery(cq.select(tAble).where(result)).getResultList();

But this only gives me the direct children, it doesn't give me the subchildren. 但这只会给我直接的孩子,而不会给我子孩子。

Thank you for your help. 谢谢您的帮助。

Entity: 实体:

@Entity
@Table(name = "table")
public final class TABLE {

    @Column(nullable = false, unique = true, length = 20)
    private String externalId;

    @Column(nullable = false, length = 50)
    private String name;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "parentId", nullable = true)
    private TABLE parent;
}

You can handle this in the domain model by making the relationship bi-directional and writing a recursive method to walk the tree. 您可以通过使关系成为双向关系并编写递归方法来遍历树来在域模型中进行处理。 One advantage of this is that it will handle children to any level. 这样做的一个优点是它将处理所有级别的孩子。

This would look something like the below and then for any instance you can do: 如下所示,然后对于任何实例,您都可以执行以下操作:

SomeEntity e = //;
e.getChildren(); //only direct children
e.getAllChildren(); //all children

Entity: 实体:

@Entity
@Table(name = "some_entity")
public final class SomeEntity {

    @Column(nullable = false, unique = true, length = 20)
    private String externalId;

    @Column(nullable = false, length = 50)
    private String name;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "parentId", nullable = true)
    private SomeEntity parent;

    @OneToMany(mappedBy = "parent")
    private List<SomeEntity> children; //or Set<>

    //returns direct children
    public List<SomeEntity> getChildren(){
        return children;
    } 

    //returns all children to any level
    public List<SomeEntity> getAllChildren(){
        getAllChildren(this);
    }

    //recursive function to walk the tree
    private List<SomeEntity> getAllChildren(SomeEntity parent){
        List<SomeEntity> allChidren = new ArrayList<>();

        for(SomeEntity child : children){
            allChildren.add(child);
            allChildren.addAll(getAllChildren(child);
        }

        return allChildren;
    }
}

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

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