OpenJPA criteriaBuilder 嵌套对象属性提取

2022-09-01 15:34:07

在 OpenJPA 中,有没有办法通过 CriteriaBuilder 获取嵌套对象属性?

这是一个小案例。

@Entity
public class X {
       private Object Y;

       // getters, setters...
}

@Entity
public class Y {
       private String Z;

       // getters, setters...
}

因此,在使用 CriteriaBuilder 时,我们使用 X 作为根,即:

@PersistenceContext
private EntityManager entityManager;

//.....

Root<X> rootObj = criteriaBuilder.from(X.class);
CriteriaQuery<X> select;

String param1 = X.getY().getZ();

// initializing predicate, default value is TRUE
Predicate predicate1 = criteriaBuilder.isNull(null);

// construct search predicate which fails miserably due to IllegalArgumentExecption
if (X != null) {
    predicate1 = criteriaBuilder.and(predicate1, criteriaBuilder.equal(rootObj.<String> get("Y.Z"), param1));
}

现在,我的悲伤是这个->get("Y.Z")

CriteriaBuilder不知道以反射方式获取Z(但是它可以并且将解决Y)。有没有办法直接从get()获得Z?

除了使用JPQL之外,我还可以想到另一种方法 - 我非常不喜欢:我想我可以将Z作为X中的属性公开(以防止OpenJPA将其持久化为列),但这听起来像是一个非常糟糕的主意:我本质上是手动扁平化对象图并在实体bean中引入不需要的垃圾, 不算平整复杂图形所需的时间或它的误差强度(它可能在很多方面出错)。@Transient

有没有办法做到这一点?任何想法都是值得赞赏的。


答案 1

呵呵,解决方案非常简单 - 它看起来非常丑陋,但它有效。

predicate1 = criteriaBuilder.and(predicate1, criteriaBuilder.equal(rootObj.get("Y").<String> get("Z"), param1));}

我真的不知道是否有更优雅的解决方案。


答案 2

对于任何任意嵌套的属性路径(“relation.subRelation.attribute”):

private Path<T> getPath(Root<T> root, String attributeName) {
    Path<T> path = root;
    for (String part : attributeName.split("\\.")) {
        path = path.get(part);
    }
    return path;
}

推荐