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 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));}
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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With