Hibernate 5.6.15.Final原生查询中EntityB审计字段映射错误
问题原因
当使用原生查询关联查询EntityA和EntityB时,两个实体的审计字段(createdBy、createdDate等)名称完全相同。由于SQL中使用o.*和d.*返回结果,导致结果集中出现同名列,Hibernate在映射结果时会将第一个实体(EntityA)的字段值覆盖第二个实体(EntityB)的同名属性,最终造成EntityB的审计字段复用EntityA的值。
解决方案
核心思路是让查询结果集中的列名唯一,明确区分两个实体的字段,以下是两种可行的实现方式:
方式一:SQL别名化 + 显式结果集映射
- 修改原生SQL,给
EntityB的所有字段(尤其是审计字段)添加唯一别名:
SELECT o.id AS a_id, o.createdBy AS a_createdBy, o.createdDate AS a_createdDate, o.modifiedBy AS a_modifiedBy, o.modifiedDate AS a_modifiedDate, -- 补充EntityA的其他字段别名 d.id AS b_id, d.createdBy AS b_createdBy, d.createdDate AS b_createdDate, d.modifiedBy AS b_modifiedBy, d.modifiedDate AS b_modifiedDate -- 补充EntityB的其他字段别名 FROM mytable1 o JOIN mytable2 d ON ...
- 在任意实体类上添加
@SqlResultSetMapping注解,定义结果映射规则:
@SqlResultSetMapping( name = "AWithBMapping", entities = { @EntityResult( entityClass = EntityA.class, fields = { @FieldResult(name = "id", column = "a_id"), @FieldResult(name = "createdBy", column = "a_createdBy"), @FieldResult(name = "createdDate", column = "a_createdDate"), @FieldResult(name = "modifiedBy", column = "a_modifiedBy"), @FieldResult(name = "modifiedDate", column = "a_modifiedDate") // 补充EntityA的其他字段映射 } ), @EntityResult( entityClass = EntityB.class, fields = { @FieldResult(name = "id", column = "b_id"), @FieldResult(name = "createdBy", column = "b_createdBy"), @FieldResult(name = "createdDate", column = "b_createdDate"), @FieldResult(name = "modifiedBy", column = "b_modifiedBy"), @FieldResult(name = "modifiedDate", column = "b_modifiedDate") // 补充EntityB的其他字段映射 } ) } )
- 执行查询时指定映射名称:
List<Object[]> rows = currentSession() .createNativeQuery(sql, "AWithBMapping") .getResultList();
方式二:改用HQL查询(业务允许时优先)
如果不需要原生SQL的特殊语法,直接使用HQL查询可以让Hibernate自动处理字段映射,避免列名冲突:
List<Object[]> rows = currentSession() .createQuery("SELECT a, b FROM EntityA a JOIN a.myEntityB b WHERE ...") .getResultList();
内容的提问来源于stack exchange,提问作者kolobok_ua
相关产品推荐
相关产品推荐

