com*_*e N 4 java jpa list criteriaquery
在使用条件查询获取列表属性时,我正在观察 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);
Run Code Online (Sandbox Code Playgroud)
(所以假设我正在获取一个列表作为对象属性的属性。)
问题是当查询返回多个结果时,secondFetch 值的重复次数与返回的行数相同。每个firstFetch应该只有一个secondFetch但有n。在这种情况下,我看到的唯一特殊之处是所有 MainObject碰巧都具有相同的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
和
@Entity
@Table(name="firstFetch")
public class FirstFetch{
//...
private List<SecondFetch> secondFetch;
@OneToMany(mappedBy="secondFetch")
public List<SecondFetch> getSecondFetch() {
return secondFetch;
}
}
Run Code Online (Sandbox Code Playgroud)
& 最后
@Entity
@Table(name="secondFetch")
public class SecondFetch {
//....
private FirstFetch firstFetch; //bidirectional
@ManyToOne
@JoinColumn(name="column")
public FirstFetch getFirstFetch() {
return firstFetch;
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在寻找某种独特的句子来应用于提取,但没有(无论如何都会是一个“补丁”......)
如果我改变
List<SecondFetch>
Run Code Online (Sandbox Code Playgroud)
为了
Set<SecondFetch>
Run Code Online (Sandbox Code Playgroud)
由于 Sets 的Keys,我会得到预期的结果,所以我确实觉得这是 JPA 列表中的一种不当行为。
不过,我不是专家,所以我可能会在映射或查询中犯一些错误。非常欢迎任何反馈以帮助解决此问题。谢谢。
尽管我使用 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);
Run Code Online (Sandbox Code Playgroud)
不使用query.distinct(true);结果集乘以secondFetch列表中的对象数量。
Hibernate 确实有类似的东西DISTINCT_ROOT_ENTITY,听起来比仅仅设置一个不同的查询更合适。但我没有进一步调查这个。我也使用 Hibernate 作为 JPA 提供程序。也许query在 JPA 中设置distinct 最终会使用与 Hibernates 相同的代码DISTINCT_ROOT_ENTITY?
| 归档时间: |
|
| 查看次数: |
12186 次 |
| 最近记录: |