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
相关产品推荐
相关产品推荐

