我有2个实体之间的@OneToMany关联( Entity1到Entity2 )。

我的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>
    java -  hibernate -sqlQuery在OneToMany上使用JOIN时映射冗余记录-LMLPHP

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


    class SomeDto {
    
     ...fields...
    
     List<Object> differFieldList;
    
    }
    

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


    提前致谢!

    最佳答案

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

    class SomeDto {
     ...fields...
     List<Object> differFieldList;
    }
    

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

    为了获得期望的数据集,需要将查询分解为两个。

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

    Query.setFirstResult(offset).setMaxResults(n)可在此处用于限制要返回的记录。如果需要将Entity2中的字段用作此查询的条件,则可以使用exist子查询加入Entity2并按Entity2字段进行过滤。

    从查询返回数据后,您可以提取item_id并将其放入集合中,并使用该集合查询实体2:
    select item_id, differ_field from Entity2 where item_id in (:itemid)
    

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

    这似乎很冗长。如果在两个实体对象之间配置了JPA @OneToMany映射,并且您的查询可以用HQL编写(您在注释中说不可能),则可以让Hibernate懒惰为您自动加载Entity2集合,在这种情况下,代码可能会很多更干净,但在后台Hibernate可能会向数据库发出更多查询请求,而延迟加载位于多面的实体。

    07-24 19:49