如何使用Spring Boot和JPA Repository将数据立即保存到数据库
问题根因
- 代码中
calculatedValueList是在save操作前查询的结果,JPA不会自动同步新保存的数据到已查询的旧列表中,所以就算save执行成功,原有列表依然是空,触发索引越界错误。 - 代码存在笔误:创建的
calculatedValue对象没有设置时间字段,反而调用了不存在的monitoredValue变量的set方法,会直接抛出异常触发事务回滚,导致实体实际未保存。 - 如果当前方法没有添加
@Transactional注解,JPA的save操作可能不会立刻刷入数据库,也会导致后续查询不到数据。
解决方案
可根据业务场景选择任意一种:
方案1:直接操作本地列表(性能最优)
save完成后直接将新创建的实体加入原有列表,不需要额外查询数据库:
@Transactional // 务必加事务注解保证保存操作生效 public void method(Double number, Integer entityId){ Entity entity= findById(entityId); CalculatedValue calculatedValue= new CalculatedValue (); LocalDateTime dateTime = LocalDateTime.now(); // 修正笔误,给正确的对象设置时间 calculatedValue.setDateTime(dateTime); List<CalculatedValue > calculatedValueList= calculatedValueservice.findAllById(entityId); if(calculatedValueList.isEmpty()){ calculatedValue.setValue(0.0); calculatedValue.setEntity(entity); // 接收save返回的持久化实体 CalculatedValue saved = calculatedValueRespository.save(calculatedValue); // 加入原有列表 calculatedValueList.add(saved); } CalculatedValue lastCalculatedValue = calculatedValueList.get(calculatedValueList.size() - 1); }
方案2:保存后重新查询列表(数据最准确,适合有其他并发写入的场景)
save执行完成后重新调用查询接口获取最新的列表数据:
@Transactional public void method(Double number, Integer entityId){ Entity entity= findById(entityId); CalculatedValue calculatedValue= new CalculatedValue (); LocalDateTime dateTime = LocalDateTime.now(); calculatedValue.setDateTime(dateTime); List<CalculatedValue > calculatedValueList= calculatedValueservice.findAllById(entityId); if(calculatedValueList.isEmpty()){ calculatedValue.setValue(0.0); calculatedValue.setEntity(entity); calculatedValueRespository.save(calculatedValue); // 重新查询最新列表 calculatedValueList= calculatedValueservice.findAllById(entityId); } CalculatedValue lastCalculatedValue = calculatedValueList.get(calculatedValueList.size() - 1); }
方案3:直接使用save返回值(无需操作列表,适合仅需获取最新保存实体的场景)
@Transactional public void method(Double number, Integer entityId){ Entity entity= findById(entityId); CalculatedValue calculatedValue= new CalculatedValue (); LocalDateTime dateTime = LocalDateTime.now(); calculatedValue.setDateTime(dateTime); List<CalculatedValue > calculatedValueList= calculatedValueservice.findAllById(entityId); CalculatedValue lastCalculatedValue; if(calculatedValueList.isEmpty()){ calculatedValue.setValue(0.0); calculatedValue.setEntity(entity); // 直接用save返回的持久化实体 lastCalculatedValue = calculatedValueRespository.save(calculatedValue); } else { lastCalculatedValue = calculatedValueList.get(calculatedValueList.size() - 1); } }
内容的提问来源于stack exchange,提问作者Gloria
相关产品推荐
相关产品推荐

