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

标签 java sql database hibernate orm

我在 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>

enter image description here

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

So what I want is to group by, for example, item_id and the List<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 retrieve limit 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/

相关文章:

java - 创建Iterable并直接传入值

java - Java 套接字是否支持全双工?

sql - 返回由 plpgsql 函数插入的记录

mysql - 如何从 mysqldump 恢复转储文件?

database - Oracle Database 12C 关机后无法启动

sql - 修改数据库时的特殊情况

java - 在不一致的数据库上 hibernate @ManyToOne

java - 哪个更快 : a conditional or a few extra arithmetic operations?

java.lang.OutOfMemory错误: Java heap space error during bulk insert to mysql database?

php - 使用 mysql 和 php 在导入时强制使用新的数据库名称