Получение всех детей и детей от родительского JPA - PullRequest
0 голосов
/ 31 января 2019

У меня есть таблица TABLE, в которой могут быть родители одного типа.В Java ребенок может связаться с родителем, но у родителя нет списка детей.

В MySQL мне удалось создать следующий запрос, который дает мне детей и дочерних элементов родителя, но я 'Я не могу перевести это на JPA Java.

Как я могу перевести этот запрос:

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

На язык Java, используя Criteria Builder и Criteria Query, я уже пробовал что-то вроде этого:

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();

Но это только дает мне непосредственных детей, но не дает мне детей.

Спасибо за вашу помощь.

Сущность:

@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;
}

1 Ответ

0 голосов
/ 31 января 2019

Вы можете справиться с этим в доменной модели, сделав двустороннее отношение и написав рекурсивный метод обхода дерева.Одним из преимуществ этого является то, что он будет обрабатывать дочерние элементы любого уровня.

Это будет выглядеть примерно так, как показано ниже, а затем для любого экземпляра, который вы можете сделать:

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

Сущность:

@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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...