OpenJPA criteriaBuilder嵌套对象属性获取

时间:2011-06-18 15:04:59

标签: java criteria-api openjpa

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

这是一个小案例。

@Entity
public class X {
       private Object Y;

       // getters, setters...
}

@Entity
public class Y {
       private String Z;

       // getters, setters...
}

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

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

现在,我的悲痛就是这个 - &gt; get("Y.Z")

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

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

有没有办法让这项工作?任何想法都表示赞赏。

2 个答案:

答案 0 :(得分:12)

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

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

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

答案 1 :(得分: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;
}