Подтвердить что ты не робот

Исключить свойства свойства вложенных объектов OpenJPA criteriaBuilder

Есть ли какой-либо способ в 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));}

Теперь мое горе → get("Y.Z")

CriteriaBuilder не знает, чтобы получить Z рефлексивно (однако он может и разрешит Y). Есть ли способ получить Z непосредственно из get()?

Помимо использования JPQL, я могу думать о другом методе, который мне очень не нравится: предположим, я мог бы показать Z как свойство @Transient в X (чтобы предотвратить OpenJPA от его сохранения как столбца), но это звучит как действительно плохая идея: я по существу сглаживаю графа объектов вручную и вношу ненужный мусор внутри объекта bean, не считая времени, необходимого для сглаживания сложного графика или ошибки (это может пойти во многих отношениях).

Есть ли способ сделать эту работу? Любые идеи приветствуются.

4b9b3361

Ответ 1

Хех, решение удивительно просто - и выглядит очень уродливо, но оно работает.

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

Я действительно не знаю, есть ли более элегантное решение для этого.

Ответ 2

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