jpa - 如何使用QueryDSL JPA加入获取集合中元素的属性
问题描述
实体如下:
class A {
Long id;
@ManyToMany
@JoinTable(name = "rel_a_b", joinColumns = @JoinColumn(name = "a_id"), inverseJoinColumns = @JoinColumn(name = "b_id"))
Set<B> bSet;
}
class B {
Long id;
@ManyToMany(mappedBy = "bSet")
Set<A> aSet;
@ManyToMany
@JoinTable(name = "rel_b_c", joinColumns = @JoinColumn(name = "b_id"), inverseJoinColumns = @JoinColumn(name = "c_id"))
Set<C> cSet;
}
class C {
Long id;
@ManyToMany(mappedBy = "cSet")
Set<B> bSet;
}
我需要选择A
实体并加入 fetchbSet
和cSet
in B
entity。使用JPA Criteria,代码如下:
final Fetch<A, B> bSetFetch = rootA.fetch("bSet", JoinType.LEFT);
bSetFetch.fetch("cSet", JoinType.LEFT);
工作正常,但我无法使用 QueryDSL 实现这一点。我试过了
final QA a = QA.a;
jpaQuery
.from(a)
.leftJoin(a.bSet, QB.b).fetchJoin()
.leftJoin(QB.b.cSet).fetchJoin()
.select(a)
但它抛出异常
query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=b,role=A.b,tableName=`b`,tableAlias=b4_,origin=a a2_,columns={a2_.id ,className=B}}] [select a
from A a
left join fetch a.bSet as b
left join fetch b.cSet]]
,如果没有fetchJoin()
,结果不包括bSet
和cSet
。谁能解决这个问题?
解决方案
从 QueryDSL 的角度来看,获取连接是正确应用的。我们还可以从生成的 JPQL 查询看起来正确的事实中观察到这一点。
这里的限制是,如果 fetch 关联的所有者被投影在 select 子句中,Hibernate 只允许 FETCH JOINS。cSet
是 上的关联B
,因此您需要投影您b
的 或省略 fetch 连接cSet
。例如:
jpaQuery
.from(a)
.leftJoin(a.bSet, QB.b).fetchJoin()
.leftJoin(QB.b.cSet).fetchJoin()
.select(a, b)
a
现在,由于 的基数,这将导致重复的结果bSet
。这只是 Hibernate 中 fetch join 的限制。
或者,您可以考虑为查询指定一个提取图:
EntityGraph postGraph = em.getEntityGraph("post");
query.setHint("javax.persistence.fetchgraph", postGraph);
有关使用 EntityGraphs 的更多信息,请参阅https://www.baeldung.com/jpa-entity-graph
推荐阅读
- python-3.x - 如何在python中用null之前的所有前面值和null之后的第一个后续值的平均值填充null值?
- excel - 当 Go 中未提供工作表/部分名称时如何从 XLS 文件中读取所有行
- javascript - 客户端未配置为通过浏览器 IdentityServer4 接收访问令牌
- ios - 编译器在 SwiftUI 中跳过嵌套的 ForEach
- python - 将类对象附加到列表的正确方法
- c# - ServiceBase.OnStop 期间的 NLog LogManager.LogFactory.Flush
- server - 如何为 tor 隐藏服务设置私有保护节点?
- c# - 避免 Unity 的全局变量。如何以及为什么?
- kdb - C API 识别空符号
- python - Python:多处理队列似乎无法访问