【发布时间】: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