You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate 5.6.15.Final原生查询中EntityB审计字段映射错误

问题原因

当使用原生查询关联查询EntityA和EntityB时,两个实体的审计字段(createdBy、createdDate等)名称完全相同。由于SQL中使用o.*和d.*返回结果,导致结果集中出现同名列,Hibernate在映射结果时会将第一个实体(EntityA)的字段值覆盖第二个实体(EntityB)的同名属性,最终造成EntityB的审计字段复用EntityA的值。

解决方案

核心思路是让查询结果集中的列名唯一,明确区分两个实体的字段,以下是两种可行的实现方式:

方式一:SQL别名化 + 显式结果集映射

  1. 修改原生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 ...
  1. 在任意实体类上添加@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的其他字段映射
            }
        )
    }
)
  1. 执行查询时指定映射名称:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:05:15