Выбор свойства вложенного объекта критерия OpenJPA critBuilder - PullRequest
13 голосов
/ 18 июня 2011

Есть ли в 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 в виде столбца), но это звучит как действительно плохая идея: я, по сути, сглаживаю граф объектов вручную и добавляю ненужный мусор в бин сущности, не считая времени, необходимого для сглаживания сложного графа, или ошибок этого (это может привести к ошибкам в так много способов).

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

Ответы [ 2 ]

14 голосов
/ 20 июня 2011

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

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

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

2 голосов
/ 27 июня 2019

Для любого произвольного пути вложенного атрибута ("ratio.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;
}
...