当使用条件查询获取列表属性时,我正在观察我认为 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;
}
}
我一直在寻找某种不同的句子来应用于 fetch 但没有(无论如何都会是一个“补丁”......)
如果我改变
List<SecondFetch>
为了
Set<SecondFetch>
多亏了 Sets' Keys,我会得到预期的结果,所以我确实觉得这是 JPA 列表中的一种不当行为。
不过,我不是专家,所以我很可能在映射或查询中犯了一些错误。非常欢迎任何反馈来帮助解决这个问题。谢谢。