Hibernate - 在OneToMany上使用JOIN时,sqlQuery映射冗余记录

Ins*_*sFi 8 java sql database orm hibernate

我在2个实体(Entity1 To 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();
Run Code Online (Sandbox Code Playgroud)

class SomeDto {
    item_id;
    some_filed1;
    ...
    differ_field;
    ...

}
Run Code Online (Sandbox Code Playgroud)

结果是 List<SomeDto>

在此输入图像描述

用灰色突出显示的字段是相同的.

所以,我想要的是group by,例如,item_idList<Object> differFieldList将作为聚合的结果.

class SomeDto {

 ...fields...

 List<Object> differFieldList;

}
Run Code Online (Sandbox Code Playgroud)

或类似的东西 Map<SomeDto, List<Object>>

我可以手动映射,但有一个麻烦:当我使用时,sqlQuery.setFirstResult(offset).setMaxResults(limit) 我检索limit记录的数量.但是有多余的行.合并后我实际上没有多少计数.

提前致谢!

JM *_*ang 2

如果您想将查询结果存储在此类的集合中:

class SomeDto {
 ...fields...
 List<Object> differFieldList;
}
Run Code Online (Sandbox Code Playgroud)

使用 sqlQuery.setFirstResult(offset).setMaxResults(n) 时,限制的记录数基于连接的结果集。合并后的记录数可能会少于预期,并且List中的数据也可能不完整。

为了获得预期的数据集,查询需要分为两部分。

在第一个查询中,您只需从 Entity1 选择数据

select * from Entity1
Run Code Online (Sandbox Code Playgroud)

这里可以使用 Query.setFirstResult(offset).setMaxResults(n) 来限制要返回的记录。如果需要使用Entity2中的字段作为此查询的条件,您可以使用exists子查询连接到Entity2并按Entity2字段进行过滤。

查询返回数据后,您可以提取 item_id 并将它们放入集合中,并使用该集合来查询实体 2:

select item_id, differ_field from Entity2 where item_id in (:itemid)
Run Code Online (Sandbox Code Playgroud)

Query.setParameterList() 可用于设置从第一个查询返回的项目 id 集合到第二个查询。然后,您需要手动将从查询 2 返回的数据映射到从查询 1 返回的数据。

这看起来很冗长。如果在2个实体对象之间配置了JPA @OneToMany映射,并且您的查询可以用HQL编写(您在评论中说不可能),您可以让Hibernate自动为您延迟加载Entity2集合,在这种情况下代码可以很多更干净,但在幕后 Hibernate 可能会生成更多对数据库的查询请求,同时延迟加载位于 Many side 的实体。