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

使用@NamedNativeQuery映射含外键实体时抛出无效列名异常

解决@NamedNativeQuery关联实体映射时的“无效列名”异常

嘿,我瞅了下你的代码,你遇到的「java.sql.SQLException: Nombre de columna no válido」问题,核心原因是原生SQL查询的列和SqlResultSetMapping的映射完全不匹配,还有部分实体属性需要的列在SQL里根本没查出来,下面我一步步给你捋清楚怎么修正:

1. 先改SqlResultSetMapping里的字段对应错误

你写的@SqlResultSetMapping里有两个明显的错误:

  • 你把BedeCategoriaHora的descripcion属性映射到了DESC_ESTADO列(这是状态表的描述),但这个属性本来应该对应分类表自己的DESCRIPCION列啊!
  • 关联的codigoEstado属性(BedeEstados类型)的映射也错了,而且你还单独声明了一个BedeEstados的@EntityResult,这会导致Hibernate试图重复映射,反而引发列名冲突。

2. 补充SQL里缺失的列

你的原生SQL只查了状态表的CODIGO_ESTADO和DESCRIPCION,但在映射里却要取HABILITADO、USUARIO_ULTIMA_MODIFICACION这些列,数据库当然找不到,直接抛异常了。得把这些列加到SQL里,还要给它们起唯一别名,避免和分类表的同名字段冲突。

3. 修正后的完整代码

修正后的@NamedNativeQuery

@NamedNativeQuery(name = "BedeCategoriaHora.obtenerCategorias",
    query ="SELECT * FROM " +
        "(SELECT q.*, rownum rn FROM " +
        "(SELECT ct.*, " +
        " e.CODIGO_ESTADO AS COD_ESTADO, E.DESCRIPCION AS DESC_ESTADO," +
        " e.HABILITADO AS ESTADO_HABILITADO," +
        " e.USUARIO_ULTIMA_MODIFICACION AS ESTADO_USUARIO_MOD," +
        " e.FECHA_ULTIMA_MODIFICACION AS ESTADO_FECHA_MOD" +
        " FROM schema.BEDE_CATEGORIA_HORA ct, schema.BEDE_ESTADOS e" +
        " WHERE ct.CODIGO_ESTADO = e.CODIGO_ESTADO" +
        " AND ct.CODIGO_CATEGORIA LIKE :pFiltroIdRegistro" +
        " AND UPPER(ct.DESCRIPCION) LIKE :pFiltroDescripcion " +
        "ORDER BY ct.CODIGO_CATEGORIA)" +
        " q) " +
        "WHERE rn BETWEEN :pPrimerRegistro AND :pUltimoRegistro",
    resultSetMapping = "obtenerCategoriasEntidad")

修正后的@SqlResultSetMapping

@SqlResultSetMapping(name = "obtenerCategoriasEntidad",
    entities = {
        @EntityResult(entityClass = BedeCategoriaHora.class, fields = {
            // 注意:name是实体类的驼峰属性名,不是数据库大写列名
            @FieldResult(name = "codigoCategoria", column = "CODIGO_CATEGORIA"),
            @FieldResult(name = "descripcion", column = "DESCRIPCION"),
            // 直接通过关联属性的子属性映射,不用单独声明BedeEstados的EntityResult
            @FieldResult(name = "codigoEstado.codigoEstado", column = "COD_ESTADO"),
            @FieldResult(name = "codigoEstado.descripcion", column = "DESC_ESTADO"),
            @FieldResult(name = "codigoEstado.habilitado", column = "ESTADO_HABILITADO"),
            @FieldResult(name = "codigoEstado.usuarioUltimaModificacion", column = "ESTADO_USUARIO_MOD"),
            @FieldResult(name = "codigoEstado.fechaUltimaModificacion", column = "ESTADO_FECHA_MOD"),
            @FieldResult(name = "topeHoras", column = "TOPE_HORAS"),
            @FieldResult(name = "objetoGasto", column = "OBJETO_GASTO"),
            @FieldResult(name = "usuarioUltimaModificacion", column = "USUARIO_ULTIMA_MODIFICACION"),
            @FieldResult(name = "fechaUltimaModificacion", column = "FECHA_ULTIMA_MODIFICACION"),
        } )
    })

几个关键注意事项

  • 属性名要严格匹配:@FieldResult的name必须和实体类的驼峰属性名完全一致,比如实体里是codigoCategoria,就不能写CODIGO_CATEGORIA。
  • 关联实体的映射方式:直接用关联属性名.子属性名的方式映射,不需要单独加另一个@EntityResult,这样能避免同名字段的冲突。
  • 列别名要唯一:两个表都有USUARIO_ULTIMA_MODIFICACION这类字段,一定要给状态表的字段起独特的别名,比如ESTADO_USUARIO_MOD,不然Hibernate会搞混到底取哪个列。

内容的提问来源于stack exchange,提问作者David Fallas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:19:08