JPA关联表查询数据时出现'Invalid Column'列名无效错误
问题原因分析
你遇到的列名无效报错和是否创建reorg_view_x实体没有直接关系,核心原因是两点:
- 你自定义查询的返回类型是
ResourceHierarchy实体,该实体通过@Id标注了resourceID为主键,还有resourceType等多个字段被标记为nullable = false,JPA实例化该实体时必须拿到这些非空字段的值,但你指定列的查询中完全没有包含这些字段,自然会报列不存在。 - 你给列指定的别名和实体字段名不匹配,比如查询中
x.faoi_prid的别名是parentResourceId,但实体里对应字段名是parentResourceID(末尾是大写ID),驼峰命名不匹配也会导致映射失败。
而select *能正常运行的原因是该语句会返回resource_hierarchy表的所有字段,包含了ResourceHierarchy实体要求的所有非空字段,所以可以正常映射。
更简单的JPA解决方案(无需创建reorg_view_x实体)
你不需要为视图单独创建实体,直接使用Spring Data JPA的投影(Projection)功能就能实现部分字段查询,步骤如下:
- 新建一个只包含你需要字段的DTO类,必须提供和查询字段顺序、类型完全匹配的全参构造方法:
import java.util.Date; public class AoiDTO { private String resourceName; private String parentResourceId; private String timeZone; private String language; private Date createdDttm; // 全参构造器,参数顺序要和后续SQL查询的列顺序完全一致 public AoiDTO(String resourceName, String parentResourceId, String timeZone, String language, Date createdDttm) { this.resourceName = resourceName; this.parentResourceId = parentResourceId; this.timeZone = timeZone; this.language = language; this.createdDttm = createdDttm; } // 按需添加getter、setter、toString方法 }
- 修改Repository中的查询方法,将返回类型改为
List<AoiDTO>即可:
@Repository public interface ResourceHierarchyRepository extends JpaRepository<ResourceHierarchy, String> { @Query(value="select distinct x.t_aoi, x.faoi_prid, rh.time_zone, rh.language, rh.created_dttm from reorg_view_x x join resource_hierarchy rh on (rh.resource_id=x.faoi_rid) where not exists (select 1 from resource_hierarchy where resource_name =x.t_aoi) and x.region= :region and trunc(x.reorg_dt) = :reorgDt", nativeQuery=true) List<AoiDTO> findAOI(@Param("reorgDt") String reorgDt,@Param("region") String region); }
可选方案:强制映射到ResourceHierarchy实体
如果你坚持要复用现有ResourceHierarchy实体作为返回类型,必须在查询语句中补充所有nullable = false的字段,并且给列指定和实体字段完全匹配的别名,示例如下:
select distinct rh.RESOURCE_ID as resourceID, x.t_aoi as resourceName, x.faoi_prid as parentResourceID, rh.RESOURCE_TYPE as resourceType, rh.time_zone as timeZone, rh.language as language, rh.CREATED_DTTM as createdDttm -- 其他所有nullable=false的字段都要按上面的格式补充 from reorg_view_x x join resource_hierarchy rh on (rh.resource_id=x.faoi_rid) where not exists (select 1 from resource_hierarchy where resource_name =x.t_aoi) and x.region= :region and trunc(x.reorg_dt) = :reorgDt
这种方案会查询很多你不需要的字段,性能不如DTO投影,不推荐使用。
内容的提问来源于stack exchange,提问作者Jeevan Gyawali
相关产品推荐
相关产品推荐

