Spring JPA POST方法修改实体后GET查询未刷新且carList为空问题
问题根因
- 双向关联维护逻辑错误
你在Customer类中定义的@OneToMany(mappedBy = "owner")说明该双向关联的维护端是Car实体的owner字段,JPA只会根据维护端的取值更新数据库外键。你仅修改了Customer端的carList集合,即使你给car设置了owner,但没有将Car的变更持久化到数据库,Car表的owner外键字段不会更新,后续GET查询从数据库拉取数据时自然查不到关联的Car数据。你控制台打印的是JPA持久化上下文的缓存对象,不是实际数据库查询的结果。 - 持久化操作缺失
你只保存了Customer实体,未保存Car实体的变更,导致关联关系没有落库。 - 金额计算逻辑错误
你的判断条件用的是折扣调整前的数值计算应付金额,但扣款前先将折扣加了5,实际扣款用的是调整后更低的折扣,逻辑不一致。
修复方案
方案一(推荐:显式保存关联实体)
- 调整金额计算顺序,先算扣款金额再更新折扣
- 在设置完car的owner后,调用
carRepository.save(car)持久化Car的变更 - 最后调用
customerRepository.save(customer)保存客户的字段变更
修改后的代码示例:
public ResponseEntity<Customer> buyCar(Long customerID, Long carID) { customerRepository .findById(customerID) .ifPresentOrElse(customer -> { carRepository.findById(carID).ifPresentOrElse(car -> { // 先按当前折扣计算应付金额,避免逻辑错误 int payableAmount = car.getPrice() * (100 - customer.getActualDiscount()) / 100; if (customer.getAmountOfCash() > payableAmount) { customer.getCarList().add(car); // 先扣钱 customer.setAmountOfCash(customer.getAmountOfCash() - payableAmount); // 再更新折扣 customer.setActualDiscount(customer.getActualDiscount() + 5); car.setOwner(customer); // 保存Car的变更(关联关系维护端,必须保存才会更新外键) carRepository.save(car); // 保存Customer的字段变更 customerRepository.save(customer); } else { throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, "Customer doesn't have enough cash"); } }, () -> { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Car not found"); }); }, () -> { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer not found"); }); return new ResponseEntity<>(HttpStatus.OK); }
方案二(通过级联配置简化操作)
如果不想单独保存Car,可以在Customer的carList字段上增加级联配置,让Customer的保存操作自动级联到关联的Car实体:
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List<Car> carList;
配置后只需要保存Customer即可,不需要单独调用carRepository.save,但该方式可控性较低,建议业务复杂时优先选择方案一。
修复完成后重新调用POST接口,再调用GET接口就能正常返回关联的carList数据。
内容的提问来源于stack exchange,提问作者77jt777
相关产品推荐
相关产品推荐

