As easy as pie!
Assuming you have the following entity:
Code:
@Entity(name = "Node")
public static class Node {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "parent_id")
private Node parent;
private String val;
@Transient
private List<Node> children = new ArrayList<>();
public Node() {}
public Node(String value) {
this.val = value;
}
public Node getParent() {
return parent;
}
public List<Node> getChildren() {
return children;
}
public void addChild(Node child) {
children.add(child);
child.parent = this;
}
}
You need a hierarchical query like this one:
Code:
Node root = (Node) doInJPA(entityManager -> {
return entityManager
.unwrap(Session.class)
.createQuery(
"SELECT n " +
"FROM Node n " +
"WHERE n.val = :val")
.setParameter("val", "x")
.setResultTransformer(new ResultTransformer() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
Node node = (Node) tuple[0];
if(node.parent != null) {
node.parent.addChild(node);
}
return node;
}
@Override
public List transformList(List collection) {
return Collections.singletonList(collection.get(0));
}
})
.uniqueResult();
});
The beauty of it is the ResultTransformer which allows you to reconstruct the hierarchical structure from the table-oriented ResultSet.