【问题标题】:JPA 2 Criteria API compare by a certain element from joined collectionJPA 2 Criteria API 按加入集合中的某个元素进行比较
【发布时间】:2016-03-02 14:22:52
【问题描述】:

也许这个问题有点不寻常,我只是不明白标准是如何工作的(很确定,因为我刚开始学习它)但现在我对以下问题有点困惑:

我实现了一个过滤器功能,它应该可以按特定标准填充一组记录。所以我们假设有以下实体:

@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 获得比较的第一个结果也会很有趣。

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

【问题讨论】:

  • 非常混乱的问题。当您尝试按名字获取时,为什么要关心对交易进行排序?你得到什么结果?你期待什么?
  • 我同意这可能会造成混淆。因此,让我们假设交易未按任何标准在列表中排序。我基本上想从最早日期的交易中获取客户的姓名。

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


【解决方案1】:

嗯,你的一些问题是因为你的实体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 并使用ManyToOne 映射来实现。

@ManyToOne
private Car car;

可能有帮助,也可能没有帮助,但这应该让你有所思考。

【讨论】:

  • 谢谢 Nicholas,但也许我应该提供有关该问题的更多详细信息。这只是一个辅助方法,它构建谓词以构建 Spring-Data-Jpa 提供的 Specification。所以在这里我无权访问实体管理器。只是 CriteriaQuery 和 CriteriaBuilder。同样在这个特定示例中,我对 Deal 并不真正感兴趣,查询应该返回由该 Deal 的属性过滤的汽车列表...
  • 发一个无法回答的问题真的没有意义吗?
  • 那种。我实际上找到了一种解决方法,根据年龄为每笔交易添加序列号,因此最旧的将始终具有 0 序列。然后使用子查询得到我需要的东西。
猜你喜欢
  • 1970-01-01
  • 2014-01-27
  • 1970-01-01
  • 2012-03-15
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多