【问题标题】:jpa criteria query duplicate values in fetched listjpa条件查询获取列表中的重复值
【发布时间】:2012-04-16 11:36:03
【问题描述】:

当使用条件查询获取列表属性时,我正在观察我认为 JPA 2 中的意外行为。

我的查询如下(摘录):

CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<MainObject> c = b.createQuery(MainObject.class);
Root<MainObject> root = c.from(MainObject.class);
Join<MainObject, FirstFetch> firstFetch = (Join<MainObject, FirstFetch>) root.fetch(MainObject_.firstFetch);
firstFetch.fetch(FirstFetch_.secondFetch); //secondFetch is a list
c.select(root).distinct(true);

(假设我正在获取一个列表作为对象属性的属性。)

问题是当查询返回多个结果时, secondFetch 值的重复次数与返回的行数一样多。每个 firstFetch 应该只有一个 secondFetch 但有 n。 我在这种情况下看到的唯一特殊性是所有 MainObjects 碰巧具有相同的 FirstFetch 实例。 所以我的猜测是连接被交叉,这是正常的,但是 JPA 无法将其 secondFetch 对象分配给每个 firstFetchs

映射不应该太特别,或多或少是这样的

@Entity
@Table(name="mainobject")
public class MainObject{
   //...
   private FirstFetch firstFetch;

   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name="mainObject_column")
   public FirstFetch getFirstFetch() {
    return firstFetch;
   }
}

@Entity
@Table(name="firstFetch")
public class FirstFetch{
   //...
   private List<SecondFetch> secondFetch;

   @OneToMany(mappedBy="secondFetch")
   public List<SecondFetch> getSecondFetch() {
      return secondFetch;
   }
}

&终于

@Entity
@Table(name="secondFetch")
public class SecondFetch {
    //....
    private FirstFetch firstFetch; //bidirectional

     @ManyToOne
     @JoinColumn(name="column")
     public FirstFetch getFirstFetch() {
        return firstFetch;
     }
}

我一直在寻找某种 distinct 语句来应用于 fetch,但没有(无论如何应该是一个“补丁”......)

如果我改变了

List<SecondFetch>

Set<SecondFetch>

感谢 Sets 的 Keys,我会得到预期的结果,所以我确实觉得这在 JPA 的列表中是一种不当行为。

不过,我不是专家,所以我很可能在映射或查询中犯了一些错误。 非常欢迎任何反馈来帮助解决这个问题。 谢谢。

【问题讨论】:

  • 您使用的是哪个 JPA 提供程序?可能是一个错误。
  • 我正在使用 JBoss 6.1.0 的默认提供程序,如果我没记错的话,这将是 Hibernate 3.6.6 Final。
  • 我遇到了完全相同的问题。我正在使用标准 api 来获取(第二个)列表,如下所示: d.fetch(FirstFetch_.secondFetch, JoinType.LEFT);

标签: java list jpa criteriaquery


【解决方案1】:

虽然我使用 JPA 标准 API 进行查询,但我遇到了完全相同的问题。

经过一些研究,我找到了您已经提到的解决方案(但由于您没有使用标准 API,所以不可用):使用 distinct

使用 JPA 标准,它看起来像这样:

CriteriaQuery<FirstFetch> query = cb.createQuery(FirstFetch.class);
Root<AbschnittC> root = query.from(FirstFetch.class);
root.fetch(FirstFetch_.secondFetch, JoinType.LEFT);
query.distinct(true); 

不使用query.distinct(true);,结果集与secondFetch 列表中的对象数量相乘。

Hibernate 确实有类似 DISTINCT_ROOT_ENTITY 的东西,这听起来比仅仅设置一个不同的查询更合适。但我没有进一步调查这一点。我还使用 Hibernate 作为 JPA 提供程序。也许在 JPA 中设置 query distinct 最终会使用与 Hibernates DISTINCT_ROOT_ENTITY 相同的代码?

【讨论】:

  • 感谢反馈,我会看看这个 DISTINCT_ROOT_ENTITY 并尽快更新
  • 你的例子只做了一个 fetch();我不认为它与上面描述的相同。
猜你喜欢
  • 2013-10-02
  • 2018-12-30
  • 1970-01-01
  • 2021-09-12
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
相关资源
最近更新 更多