You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过/exist接口编辑预订后实体「消失」问题排查与修复咨询

问题:预订编辑后「自行消失」但数据库仍存在,字段无法修改

问题现象

  • 创建预订后调用/exist接口编辑,业务层面出现预订「自行消失」的情况,但通过MySQL查询确认Reservation实体仍存在于数据库中
  • 调试过程无错误提示,无法将原本非null的字段从null状态修改回来

相关控制器代码

@PostMapping("/exist")
public ResponseEntity createreservationExist(@RequestBody Map<Object, Object> payLoad ) throws URISyntaxException, ParseException {

    long id=(Integer)payLoad.get("id");
    Reservation reservation=reservationServices.getreservationById(id);

    String creditCardNumber="";

    creditCardNumber=(String)payLoad.get("creditCardNumber");
    String note=(String)payLoad.get("note");
    reservation.setNote(note);

    DateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
    java.util.Date utilDate=simpleDateFormat.parse((String)payLoad.get("dateOfEvent"));
    Date ofDate=new java.sql.Date(utilDate.getTime());
    reservation.setName((String)payLoad.get("name"));
    reservation.setDateOfEvent(ofDate);
   ArrayList<Order> orders=new ArrayList<>(reservation.getOrders());
    double total=0;
    double tax=0.15;
    for(int i=0;i<orders.size();i++){
            total+=foodServices.getFoodByName(orders.get(i).getFood()).getPrice()*orders.get(i).getQuantity();
    }

        total=total+(total*tax);
        total=(total * 100) / 100.0;

    Transaction transaction=new Transaction(creditCardNumber,total,reservation);
    try{
    transactionServices.removetransaction(reservation.getTransaction().getId());}
    catch(Exception e){

    }


    reservation.setTransaction(transaction);

    reservationServices.saveReservation(reservation);
    return ResponseEntity.ok().build();
}

原因分析

  1. 异常被静默吞掉:删除旧Transaction的try/catch块未做任何处理,若旧交易记录不存在或删除失败,异常被隐藏,后续关联新交易的逻辑可能出现问题,导致预订关联数据异常,业务层面无法正常查询到预订
  2. 实体持久化状态异常:如果reservationServices.getreservationById(id)获取的实体脱离了当前持久化上下文(比如查询使用了只读事务或查询后上下文关闭),修改字段后调用saveReservation可能无法触发数据库更新,导致字段修改不生效
  3. 字段赋值无null校验:从payLoad中获取的name、note等字段如果为null,会直接覆盖原有非null值,导致字段被设为null,业务层面误判预订“消失”
  4. 日期转换无异常处理:SimpleDateFormat.parse若传入无效日期格式会抛出ParseException,但控制器直接抛出未做处理,可能导致请求中断但无明确反馈,表现为预订编辑后“消失”

修复方法

  1. 移除异常静默处理,添加错误日志与反馈
    删除空catch块,改为记录错误日志并抛出明确异常,确保问题可追踪:

    try {
        transactionServices.removetransaction(reservation.getTransaction().getId());
    } catch(Exception e) {
        log.error("删除旧交易记录失败,预订ID: {}", id, e);
        throw new RuntimeException("更新预订失败:无法删除旧交易记录");
    }
    
  2. 确保实体处于持久化上下文
    检查reservationServices.getreservationById的实现,确保查询在事务上下文内;若使用JPA,修改后调用merge方法确保实体状态同步到数据库:

    // 修改后合并实体到持久化上下文
    reservation = reservationServices.mergeReservation(reservation);
    

    或在saveReservation方法中使用entityManager.merge(reservation)替代persist

  3. 添加字段null校验,保留原有值
    从payLoad取值时判断是否为null,仅在非null时覆盖原有字段值:

    String note = (String) payLoad.get("note");
    if (note != null) {
        reservation.setNote(note);
    }
    
    String name = (String) payLoad.get("name");
    if (name != null) {
        reservation.setName(name);
    }
    
  4. 完善日期转换的异常处理
    对日期解析添加异常捕获,返回明确的错误响应:

    Date ofDate;
    try {
        DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        java.util.Date utilDate = simpleDateFormat.parse((String) payLoad.get("dateOfEvent"));
        ofDate = new java.sql.Date(utilDate.getTime());
        reservation.setDateOfEvent(ofDate);
    } catch (ParseException e) {
        log.error("日期格式错误,传入值: {}", payLoad.get("dateOfEvent"), e);
        return ResponseEntity.badRequest().body("日期格式错误,请使用yyyy-MM-dd格式");
    }
    
  5. 检查实体关联配置
    确认Reservation与Transaction的关联注解(如@OneToOne)配置正确,级联规则符合业务逻辑,避免因关联失败导致业务查询无法获取预订

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 01:30:13