【发布时间】:2023-03-20 13:19:01
【问题描述】:
我在一个项目中工作,其中一项任务是创建动态查询,并可以按相关的惰性 oneToMany 实体属性进行排序。我的第一次尝试是使用 Criteria-api,但是当我需要查询“非相关”字段时,我无法理解它,所以我切换到了普通的 JPQL,在那里我可以更清楚地表达自己
然而,普通的 JPQL 似乎也有问题。用例之一是使用相关实体(例如连接提取)获取 AggregateRoots,其中谓词可以匹配 AggregareRoot 或相关实体属性的值。同样适用于订购部分。现在结果也需要分页。
我可以实现所有这些,但是在执行查询时我得到“HHH000104:firstResult/maxResults specified with collection fetch; apply in memory!”。经过一番谷歌搜索后,我最终找到了https://vladmihalcea.com/fix-hibernate-hhh000104-entity-fetch-pagination-warning-message/,在那里得到了解释并提供了 2 个解决方案。第一个解决方案只是查询 AggregateRoots 的 ID:s(没有连接提取),然后使用这些 ID 查询实际的数据图(使用连接提取)。
现在大问题来了,我需要能够按一些聚合根字段或相关实体字段(全部由 UI 指定)排序。我的第一个天真的解决方案只是“从 AggregateRoot 中选择不同的 a.id 作为 id ...”,但是当它需要排序时,我得到了 ORDER BY items must appear in the select list if SELECT DISTINCT is specified。经过一番思考后,我意识到我可以创建所有可能的“排序依据”字段的投影(AggregateRoot.ID 是其中之一,在排序依据子句中用作最后手段以使结果连贯),然后从那里获取 AggregateRoot ID传递给实际的数据查询。但是现在我最终遇到了 ORM 阻抗不匹配的主要问题(如我所见)。基本上最后我有以下类型的 SQL
选择 不同的聚合0_.id 为 col_0_0_, relatedEntity_.name 为 col_6_0_ 从 聚合根聚合0_ 内部联接 相关实体相关实体_ 在 aggregate0_.id=relatedEntity_.aggregate_id 订购 col_6_0_ DESC, col_0_0_ offset 0 rows 仅获取接下来的 3 行
最终会得到结果
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
}
</style>
</head>
<body>
<table>
<tr>
<td><b>col_0_0_</b></td><td><b>col_6_0_</b></td>
</tr>
<tr>
<td>1</td><td>CCC</td>
</tr>
<tr>
<td>1</td><td>BBB</td>
</tr>
<tr>
<td>2</td><td>AAA</td>
</tr>
</table>
</body>
</html>
所以现在我只有 2 个唯一 ID(而不是 3 个)作为参数传递给实际的数据查询。我还尝试给出提示 HINT_PASS_DISTINCT_THROUGH,如此处所述https://vladmihalcea.com/jpql-distinct-jpa-hibernate/ 但我仍然只得到 2 个聚合根 ID(hibernate-core 版本为 5.4.1.final)。任何建议将不胜感激!
【问题讨论】:
标签: java hibernate jpa orm spring-data