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

Spring Boot原生查询列值为null时映射实体为null如何修复

问题根因
  • 实体类未遵循JPA复合主键规范:你直接在OrderKey类中声明了两个@Id字段,但没有绑定@IdClass对应的复合主键类,JPA结果映射时主键判定逻辑异常,会错误地将非主键字段为null的行映射为null实体。
  • Repository泛型参数不匹配:CrudRepository第二个泛型参数要求填写主键类型,你当前使用复合主键却填写了Long,会加剧映射逻辑异常。
  • 补充:你贴出的OrderKey类缺少@Entity注解,JPA无法识别该类为可映射的实体类。
修复方案

方案1:规范JPA复合主键写法(推荐)

步骤1:定义复合主键类

import java.io.Serializable;
import java.util.Objects;

public class OrderKeyId implements Serializable {
    private long orderId;
    private String keyType;

    // 必须保留空构造方法
    public OrderKeyId() {}

    public OrderKeyId(long orderId, String keyType) {
        this.orderId = orderId;
        this.keyType = keyType;
    }

    // 必须重写equals和hashCode方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        OrderKeyId that = (OrderKeyId) o;
        return orderId == that.orderId && Objects.equals(keyType, that.keyType);
    }

    @Override
    public int hashCode() {
        return Objects.hash(orderId, keyType);
    }
}

步骤2:修改OrderKey实体类

import javax.persistence.*;
import java.io.Serializable;

@Entity // 补充实体注解
@IdClass(OrderKeyId.class) // 绑定复合主键类
public class OrderKey implements Serializable {

    private static final long serialVersionUID = 10L;

    @Id
    @Column(name = "ORDER_ID")
    public long orderId;

    @Id
    @Column(name = "KEY_TYPE")
    public String keyType;

    @Column(name = "KEY")
    public String key;

    @Column(name = "VERSION")
    public String version;

}

步骤3:修改Repository泛型参数

@Repository
// 将第二个泛型参数替换为自定义复合主键类OrderKeyId
public interface OrderRepository extends CrudRepository<OrderKey, OrderKeyId> {

    @Query(value = "SELECT l.[ORDER_ID]," +
            "l.[KEY_TYPE], " +
            "l.[KEY]," +
            "l.[VERSION]  " +
            "FROM [ORDER_TABLE] l " +
            "WHERE [ORDER_ID] = :orderId",
            nativeQuery = true)
    List<OrderKey> findAll(@Param("orderId") Long orderId);

}

方案2:临时修复(不调整实体结构)

如果暂时不想修改实体和主键结构,可以在原生查询中用COALESCE函数将null的VERSION字段转为空字符串,避免触发映射异常:

@Query(value = "SELECT l.[ORDER_ID]," +
        "l.[KEY_TYPE], " +
        "l.[KEY]," +
        "COALESCE(l.[VERSION], '') as VERSION  " + // 处理null值
        "FROM [ORDER_TABLE] l " +
        "WHERE [ORDER_ID] = :orderId",
        nativeQuery = true)
List<OrderKey> findAll(@Param("orderId") Long orderId);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:06:04