问题
I have a table TABLE that can have parents of the same type. In Java the child can reach the parent but the parent doesn't have a list of children.
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.
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:
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;
}
回答1:
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;
}
}
来源:https://stackoverflow.com/questions/54459083/getting-all-children-and-subchildren-from-parent-jpa