JPA 2 Criteria API按联合集合中的某个元素进行比较

时间:2016-03-02 14:22:53

标签: hibernate spring-data-jpa criteria criteria-api

也许问题有点不寻常,我只是不知道Criteria如何运作(非常肯定,因为我刚开始学习它)但现在我对以下问题感到困惑:

我实现了一个过滤功能,可以按特定条件填充一组记录。所以我们假设有以下实体:

@Entity
public class Car {

    @OneToMany
    private List<Deal> deals; 

}

@Entity
public class Deal {

    private Customer customer;

    private DateTime dealDate; 
}

现在我必须通过第一个客户名称来过滤汽车记录。所以在理论上它看起来像:

private static List<Predicate> buildPredicates(Root root, CriteriaQuery query,
 CriteriaBuilder builder, CarFilter filter) {
    List<Predicate> predicates = new ArrayList<>();
    ...
predicates.add(
    builder.like(            
            root.get(Car_.deals.sortByDealDateComparator().first().customer.name), 
            filter.getFirstCustomerName()));
    ...
    return predicates;
}

我相信这些交易应该首先加入,然后以某种子查询或其他方式进行排序。但是,如何使用CriteriaQuery获得第一个比较结果也很有趣。

我想我的方法不对,所以任何建议都会受到欢迎。

1 个答案:

答案 0 :(得分:0)

好吧,你的一些问题是因为你的实体hierarchy。您在层次结构的根目录中有Cars,但您需要使用Deals。如果您使用Deals,可以(或多或少)直接获得您想要的内容:

CriteriaQuery<Deal> q = cb.createQuery(Deal.class);
Root<Deal> root = q.from(Deal.class);
CriteriaQuery<Deal> s = q.select(root).where(
        cb.like(root.get("customer").get("name").as(String.class), "Karl"  )
    ).orderBy(cb.asc(root.get("dealDate")));
Deal deal = em.createQuery(s).getResultList().get(0);

当然,我没有尝试使用实体的元数据版本。这里,根设置为Deallike predicate用于按名称获取Customers,并使用cb.asc对结果列表进行排序。第一个Deal取自结果列表,其中包含Customer

如果您想返回Car,则需要bidirectional关系映射,您可以将Car添加到Deal并映射到{{1} }}

ManyToOne

可能或可能没有帮助,但这应该给你一些思考。