开发者

OpenJPA criteriaBuilder nested object property fetch

Is there any way in OpenJPA to get hold of a nested object property via CriteriaBuilder?

Here's a small case.

@Entity
public class X {
       private Object Y;

       // getters, setters...
}

@Entity
public class Y {
       private String Z;

       // getters, setters...
}

So, when using CriteriaBuilder, we use X as Root, i.e.:

@PersistenceContext
private EntityManag开发者_高级运维er 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));
}

Now, my grief is this -> get("Y.Z")

CriteriaBuilder doesn't know to fetch Z reflectively (however it can and will resolve Y). Is there any way to get hold of Z directly from get()?

Apart from using JPQL, I can think of one other method - which I dislike immensely: I suppose I could have exposed Z as an @Transient property in X (as to prevent OpenJPA from persisting it as a column), but that sounds like a Really Bad Idea: I am essentially flattening out an object graph manually and introduce unneeded garbage inside the entity bean, not counting the time needed to flatten out a complex graph or the error-proness of this (it can go awry in so many ways).

Is there a way to make this work? Any ideas are appreciated.


Heh, the solution is suprisingly simple - and it looks really ugly, but it works.

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

I really don't know if there is a more elegant solution to this.


For any arbitrary nested attribute path ("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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜