gpt4 book ai didi

jpa - 如何使用 QueryDSL JPA 加入获取集合中元素的属性

转载 作者:行者123 更新时间:2023-12-05 03:52:46 24 4
gpt4 key购买 nike

实体如下:

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 实体并在B 实体中加入fetch bSetcSet。使用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(),结果不包括bSetcSet。谁能解决这个问题?

最佳答案

从 QueryDSL 的角度来看,提取连接已正确应用。我们还可以从生成的 JPQL 查询看起来正确的事实中观察到这一点。

这里的限制是,如果提取关联的所有者在 select 子句中投影,Hibernate 只允许 FETCH JOINS。 cSetB 上的关联,因此您需要投影您的 b 或省略 cSet 。例如:

jpaQuery
.from(a)
.leftJoin(a.bSet, QB.b).fetchJoin()
.leftJoin(QB.b.cSet).fetchJoin()
.select(a, b)

现在,由于 bSet 的基数,这将导致 a 的重复结果。这只是 Hibernate 中获取连接的一个限制。

或者,您可以考虑为查询指定一个提取图:

EntityGraph postGraph = em.getEntityGraph("post");
query.setHint("javax.persistence.fetchgraph", postGraph);

有关使用 EntityGraphs 的更多信息,请参阅 https://www.baeldung.com/jpa-entity-graph

关于jpa - 如何使用 QueryDSL JPA 加入获取集合中元素的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62056765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com