Querydsl: fetchJoin(JoinFlag) 取消

创建于 2020-09-17  ·  6评论  ·  资料来源: querydsl/querydsl

fetchJoin对于遍历实体图很有用。 但是,当需要投影时,我们不能使用它。

当需要投影(例如最小/最大/计数)时,我想实例化一个原始的 JPAQuery,然后查询 fetchJoin-canceled JPAQuery。 例如(在 Kotlin 中):

val q = from(foo).innerJoin(bar).fetchJoin().where(...).orderBy(...)

val maxId = q.select(foo.id.max()).removeFlag(FETCH).fetchOne()

val result = q.where(foo.id.lt(maxId)).fetch()

DefaultQueryMetadataaddJoinFlag(...)但没有removeJoinFlag(...) 。 拥有它会很棒!

jpa question

所有6条评论

Query API 遵循构建器模式,其中联接标志仅应用于最后一个联接。 没有明智的方法来使用removeFlag ,因为它必须在添加预期标志后立即调用以获得可靠结果。

正确的方法是从连接列表中找到查询根,并从连接中删除标志:

即: query.getMetadata().getJoins().stream().filter(join -> join.getTarget().equals(bar)).getFlags().remove(FETCH)

我们可以考虑一个 API 来更流畅地检索查询根,即query.getMetadata().getJoin(bar).getFlags().remove(FETCH)

不幸的是,我不得不拒绝removeFlag的想法,因为它不会按预期工作。

@jwgmeligmeyling
首先谢谢你的回复👍

我不明白它不会按预期工作。

我已经使用 Java 反射实现了它,如下所示(它有效!):

                val joinFlagsField: Field = metadata.javaClass.declaredFields
                    .first { it.name == "joinFlags" }
                    .also { it.isAccessible = true }

                val joinFlags: Set<JoinFlag> = joinFlagsField.get(metadata) as Set<JoinFlag>

                if (joinFlags.contains(FETCH)) {
                    joinFlagsField.set(metadata, CollectionUtils.removeSorted(joinFlags, FETCH))
                }

我不喜欢那样,当然。 因为正如我所说,它是使用反射实现的。

从连接列表中查找查询根的方法,是的,它是一种明确有效的方法,但不是通用的。 我想让我的 ItemReader 通用; 作为您的方法,ItemReader 必须知道什么是连接路径。

我希望你再考虑一次。 🙏

它不是通用的,因为一个人可能有几个连接:

from(foo)
    .innerJoin(bar).fetchJoin()
    .innerJoin(baz).fetchJoin()
    .innerJoin(buz)
   .where(...).orderBy(...)

在这里调用removeFetchJoin将尝试从buz删除 fetch 标志 - 它甚至不存在 - 并且它将保留barbaz的 fetch 连接独自的。

通过使用getMetadata().getJoins()#getFlags()您的实现将更加可靠(并且不需要任何反射)

请注意,您也可以删除所有FETCH标志: query.getMetadata().getJoins().forEach(join -> join.getFlags().remove(FETCH))

@jwgmeligmeyling
感谢您的帮助! 就我而言,你最后的帮助是最好的!

祝你好运!

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

rafaelszp picture rafaelszp  ·  5评论

intuitiveminds picture intuitiveminds  ·  8评论

okihouse picture okihouse  ·  5评论

d-schmidt picture d-schmidt  ·  5评论

Ghalleb picture Ghalleb  ·  4评论