【问题标题】:JPA query a collection using between clauseJPA 使用 between 子句查询集合
【发布时间】:2014-04-15 15:39:58
【问题描述】:

我的实体有另一个实体的集合,我需要对其执行BETWEEN 标准。 我不想使用本机查询。 我正在尝试使用标准 API 来实现这一点。

以下是我的实体的简短 sn-p。

@Entity
@Table(name = "ref_dates")
public class Dates{
    @Id
    @Column(name = "ID")
    private int id;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinTable(
    name="ref_dates_prg",
    joinColumns = @JoinColumn( name="DATE_PRG_ID"),
    inverseJoinColumns = @JoinColumn( name="DATE_ID")
 )    
 private Set<DateInfo> dates;

}

它还有其他几个属性,geter/setter 等,我在这里没有提到。 我需要使用between 子句查询DateInfo 对象中的id 的Set。 我尝试使用Expression&lt;Set&lt;DateInfo&gt;&gt;,但没有到达任何地方。 感谢大家的帮助。

这是我建立的标准。

final CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

final CriteriaQuery<NetPrgTimePeriod> criteriaQuery = criteriaBuilder.createQuery(Dates.class);

List<Predicate> criteriaList = new ArrayList<Predicate>();

final Root<Dates> root = criteriaQuery.from(Dates.class);

Join<Dates, DateInfo> dateJoin = root.join("dates", JoinType.LEFT);

Predicate runDatesRange = criteriaBuilder.between(
        dateJoin.<Integer> get("id"), startDate.getId(), endDate.getId());

criteriaList.add(runDatesRange);

Join<Dates, TimeInfo> timeJoin = root.join("times", JoinType.LEFT);

Predicate timeBlocksRange = criteriaBuilder.between(
        timeJoin.<Integer> get("id"), startTime.getId(), endTime.getId());

criteriaList.add(timeBlocksRange);

criteriaQuery.where(criteriaBuilder.and(criteriaList.toArray(new Predicate[0])));

TypedQuery<NetPrgTimePeriod> query = em.createQuery(criteriaQuery);

List<Dates> results = query.getResultList();

【问题讨论】:

  • 这是您的完整实体吗?因为就目前而言,您的 Set 最终将成为一个 blob 列 dates,而不是 FK 映射。

标签: java jpa persistence criteria


【解决方案1】:

假设您实际上正确映射了您的收藏,您似乎缺少的主要部分是Join

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Dates> query = cb.createQuery(Dates.class);

Root<Dates> root = query.from(Dates.class);
Join<Dates, DateInfo> infos = root.join("dates", JoinType.LEFT);

query.distinct(true);
em.createQuery(query.where(cb.between(infos.<Integer>get("id"), 1, 10))).getResultList();

当然,您可以在我使用字符串的地方替换元模型字段(这也将不再需要这个丑陋的 &lt;Integer&gt; 选择器 - 假设您的 id 一个整数)。

【讨论】:

  • 谢谢,我已经编辑了我的原始代码以包含更合适的映射。已在集合的实体中指定连接。
  • @user3536652 是的,但我说的是查询中使用的Join 接口(此处命名为infos)。如果这对您不起作用,您可以使用您尝试过的条件查询来编辑您的帖子,哪些不起作用?
  • 谢谢@Mabi,这会让我开始。将向您更新结果。
  • 没有按预期工作,它返回更多行和额外的连接。该集合包含所有值而不是过滤值(它应该过滤集合吗?)我添加了我的标准构建代码。
  • @user3536652 我已将帖子编辑为仅包含 distinct 行。这摆脱了你的第一个问题。至于第二个:Hibernate 返回集合的所有元素是正常行为。你需要一个额外的结果转换器或 java 中的过滤器代码。
猜你喜欢
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 2019-03-15
  • 1970-01-01
相关资源
最近更新 更多