Kji*_*jir 5 java jpa criteria-api
我想使用JPA CriteriaBuilder创建一个查询,我想添加一个ORDER BY子句.这是我的实体:
@Entity
@Table(name = "brands")
public class Brand implements Serializable {
    public enum OwnModeType {
        OWNER, LICENCED
    }
    @EmbeddedId
    private IdBrand id;
    private String code;
    //bunch of other properties
}
嵌入式课程是:
@Embeddable
public class IdBrand implements Serializable {
    @ManyToOne
    private Edition edition;
    private String name;
}
我构建查询的方式是这样的:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Brand> q = cb.createQuery(Brand.class).distinct(true);
Root<Brand> root = q.from(Brand.class);
if (f != null) {
    f.addCriteria(cb, q, root);
    f.addOrder(cb, q, root, sortCol, ascending);
}
return em.createQuery(q).getResultList();
这里有一些函数:
public void addCriteria(CriteriaBuilder cb, CriteriaQuery<?> q, Root<Brand> r) {
}
public void addOrder(CriteriaBuilder cb, CriteriaQuery<?> q, Root<Brand> r, String sortCol, boolean ascending) {
    if (ascending) {
        q.orderBy(cb.asc(r.get(sortCol)));
    } else {
        q.orderBy(cb.desc(r.get(sortCol)));
    }
}
如果我尝试设置sortCol为像"id.name"我得到以下错误:
javax.ejb.EJBException:java.lang.IllegalArgumentException:无法解析路径的属性[id.name]
知道我怎么能做到这一点?我尝试在网上搜索,但是我找不到关于这一点的暗示......如果我能够做一个类似的事情,ORDER BY当我有一段@ManyToOne关系时也会很棒(例如"id.edition.number")
问题是您对JPA路径使用的理解.JPA手册说:
通过重用点(.)运算符,可以进一步扩展其类型为可持久用户类的路径表达式.例如,c.capital.name是一个嵌套路径表达式,它从Capital实体对象继续到其name字段.仅当路径表达式的类型也是用户定义的可持久类时,才能进一步扩展路径表达式.点(.)运算符不能应用于简单类型(数字,布尔值,字符串,日期)的集合,映射和值.
在您的情况下,您使用了id.edition.number,其中IdBrand(id)不是用户可持久化的类.
解决方案是以这种方式构建路径表达式:root.get("id").get("edition.number");
为避免此类问题,您可以编写路径构建器,该构建器基于javax.persistence.metamodel.Attribute.PersistentAttributeType将决定路径的构建方式.对于基本元素 - 使用.get(),对于集合元素使用.join().
为了了解您的错误,您需要阅读有关JPA路径的更多信息.这是一本关于JPA路径的好手册.
| 归档时间: | 
 | 
| 查看次数: | 5313 次 | 
| 最近记录: |