【问题标题】:OpenJPA criteriaBuilder nested object property fetchOpenJPA criteriaBuilder 嵌套对象属性获取
【发布时间】:2011-09-17 19:41:21
【问题描述】:

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)。有什么方法可以直接从 get() 中获取 Z 吗?

除了使用 JPQL,我还可以想到另一种方法——我非常不喜欢这种方法:我想我可以将 Z 暴露为 X 中的 @Transient 属性(以防止 OpenJPA 将其作为列持久化),但是这听起来像是一个非常糟糕的主意:我实际上是在手动展平对象图并在实体 bean 中引入不需要的垃圾,而不是计算展平复杂图所需的时间或它的错误倾向(它可能会出错有很多方法)。

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

【问题讨论】:

    标签: java criteria-api openjpa


    【解决方案1】:

    呵呵,解决方案出奇的简单——虽然看起来很丑,但确实有效。

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

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

    【讨论】:

    • 有如果你使用元模型:predicate1 = criteriaBuilder.and(predicate1, criteriaBuilder.equal(rootObj.get(X_.Y).get(Y_.Z), param1));}
    • 是的,但是我们不使用元模型类,我个人发现这种链接语法非常出乎意料,尤其是链中最后一个 getter 的类型声明。可以说,它可以在引擎盖下使用反射来更清晰地定义(并且更容易使用),但是 - 例如,这种方式必须这样做。
    • 我确认这个解决方案即使对我来说也很有效。对于丑陋的部分,我的建议是按照委托或 dao 模式将此代码与您的代码隔离到一个单独的类中
    • 这是一个gist,用于处理带有简单字符串的子路径的基本 JPA 存储库。
    【解决方案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;
    }
    

    【讨论】:

    • 您的解决方案看起来完美而通用。但是当我在我的代码中尝试它时得到异常 java.lang.IllegalArgumentException: Parameter value [com.example.model.Employee@5be1ea20] did not match expected type [java.lang.String (n/a)] 你能纠正吗我做错了什么
    猜你喜欢
    • 2018-02-06
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多