我在 2 个实体(Entity1 到 Entity2)之间有 @OneToMany 关联。
我的 sqlQueryString 包括以下步骤:
-
select ent1.*, ent2.differ_field from Entity1 as ent1 left outer join Entity2 as ent2 on ent1.item_id = ent2.item_id
- 添加一些子查询并将结果写入 some_field2、some_field3 等。
执行:
Query sqlQuery = getCurrentSession().createSQLQuery(sqlQueryString)
.setResultTransformer(Transformers.aliasToBean(SomeDto.class));
List list = sqlQuery.list();
和
class SomeDto {
item_id;
some_filed1;
...
differ_field;
...
}
所以结果是 List<SomeDto>
用灰色突出显示的字段是相同的。
So what I want is to
group by
, for example,item_id
and theList<Object> differFieldList
would be as aggregation result.
class SomeDto {
...fields...
List<Object> differFieldList;
}
或类似的东西 Map<SomeDto, List<Object>>
I can map it manually but there is a trouble: When I use
sqlQuery.setFirstResult(offset).setMaxResults(limit)
I retrievelimit
count of records. But there are redundant rows. After merge I have less count actually.
提前致谢!
最佳答案
如果您想将查询结果存储在此类的集合中:
class SomeDto {
...fields...
List<Object> differFieldList;
}
当使用 sqlQuery.setFirstResult(offset).setMaxResults(n) 时,限制的记录数基于连接的结果集。合并后的记录数可能比预期少,List中的数据也可能不完整。
要获得预期的数据集,需要将查询分为两部分。
在第一个查询中,您只需从 Entity1 中选择数据
select * from Entity1
这里可以使用Query.setFirstResult(offset).setMaxResults(n)来限制要返回的记录数。如果 Entity2 中的字段需要用作此查询中的条件,您可以使用 exists 子查询连接到 Entity2 并按 Entity2 字段进行过滤。
一旦查询返回数据,您可以提取 item_id 并将它们放入一个集合中,然后使用该集合来查询实体 2:
select item_id, differ_field from Entity2 where item_id in (:itemid)
Query.setParameterList() 可用于设置从第一个查询返回的item id 集合到第二个查询。然后,您需要手动将从查询 2 返回的数据映射到从查询 1 返回的数据。
这看起来很冗长。如果在两个实体对象之间配置了JPA @OneToMany 映射,并且你的查询可以用HQL 编写(你在评论中说不可能),你可以让Hibernate 自动为你延迟加载Entity2 集合,在这种情况下代码可以很多更清洁,但在幕后,Hibernate 可能会在延迟加载位于 Many 端的实体时生成更多对 DB 的查询请求。
关于java - Hibernate - 在 OneToMany 上使用 JOIN 时 sqlQuery 映射冗余记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31976076/