You need to enable JavaScript to run this app. Spring Data JPA实现存在则更新不存在则插入时报空指针如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data JPA实现存在则更新不存在则插入时报空指针如何解决

Spring JPA 单参数判断更新/插入实现及空指针问题修复

错误原因排查

  1. 最直接的空指针来自Service层else分支:当查询结果为空时,document为null,直接调用document.getId()等方法必然抛出空指针异常。
  2. 控制器参数引用错误:接收的ID参数命名为pId,调用Service时错误使用未定义的Id变量。
  3. 非法命名:case是Java关键字,不能直接作为变量名、属性名使用,会导致编译或运行异常。
  4. JPA实体类缺少无参构造函数:JPA规范要求实体类必须提供无参构造,否则会在数据映射时报错。
  5. String类型主键的生成策略错误:@GeneratedValue默认适配数值型主键,String主键需要指定UUID等生成策略。

修复后代码

控制器层

@RequestMapping(path="/updatedm",method = RequestMethod.POST)
public Boolean updateDMStatus(@RequestParam("country") String country,
                             @RequestParam("Id") String pId,
                             // 接收参数映射原case字段,内部用caseNum避免关键字冲突
                             @RequestParam("case") String caseNum,
                             @RequestParam("status") String status,
                              @RequestParam("updatedBy") String updatedBy){
    // 修正参数引用,传入pId
    return eaDataStoreService.updateDM(country, pId, caseNum, status, updatedBy);
}

实体类

@Data
@ToString
@Entity
@Table(name = "DMStatus")
@NoArgsConstructor // 新增JPA要求的无参构造
public class DMValidated{
    @Id
    // 适配String主键的UUID生成策略
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    private String id;
    @Column(name = "country")
    private String country;
    @Column(name = "Id")
    private String Id;
    // 实体属性改为caseNum,映射数据库原Case字段
    @Column(name = "Case")
    private String caseNum;
    @Column(name = "status")
    private String status;
    @Column(name = "updatedBy")
    private String updatedBy;

    public  DMValidated(String country, String Id,
                        String caseNum, String status, String updatedBy){
        this.country = country;
        this.Id = Id;
        this.caseNum = caseNum;
        this.status = status;
        this.updatedBy = updatedBy;
    }
}

Repository层

public interface DMValidatedRepository extends CrudRepository<DMValidated, String> {
    // 属性名同步修改为caseNum
    DMValidated findByCaseNum(String caseNum);
}

Service层

@Service
public class EaDataStoreService {
    @Autowired
    private DMValidatedRepository dmValidatedRepository;

    @Transactional // 新增事务保证操作原子性
    public boolean updateDM(String country, String Id, String caseNum, String status,String updatedBy) {
        DMValidated document = dmValidatedRepository.findByCaseNum(caseNum);
        if(document != null){
            // 存在则更新目标字段
            document.setStatus(status);
            document.setUpdatedBy(updatedBy);
            dmValidatedRepository.save(document);
        }else{
            // 不存在则新建对象赋值,不要操作空对象
            document = new DMValidated(country, Id, caseNum, status, updatedBy);
            dmValidatedRepository.save(document);
        }
        return true;
    }
}

可选优化

  • 如果仅需判断记录是否存在,可在Repository中添加boolean existsByCaseNum(String caseNum)方法,无需查询全量实体数据,性能更高。
  • 建议对入参做非空校验,避免传入null值引发其他异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 22:15:01