Spring Data JPA实现存在则更新不存在则插入时报空指针如何解决
Spring JPA 单参数判断更新/插入实现及空指针问题修复
错误原因排查
- 最直接的空指针来自Service层else分支:当查询结果为空时,
document为null,直接调用document.getId()等方法必然抛出空指针异常。 - 控制器参数引用错误:接收的ID参数命名为
pId,调用Service时错误使用未定义的Id变量。 - 非法命名:
case是Java关键字,不能直接作为变量名、属性名使用,会导致编译或运行异常。 - JPA实体类缺少无参构造函数:JPA规范要求实体类必须提供无参构造,否则会在数据映射时报错。
- 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
相关产品推荐
相关产品推荐

