Day1把环境搭好了,今天的目标是实现真正的业务逻辑——库存判断和订单评审流程(对应试卷5.1~5.3条)。结果计划没赶上变化,整个上午几乎都耗在了满屏的红色波浪线里,直到中午才看到控制台跳出"Started SalesOrderApplication"。这篇记录一下今天踩的8个坑,给同样在推进这个课设的同学参考。

今天的目标
在Day1骨架的基础上,给SalesOrderService.createOrder()加上两块核心逻辑:
库存判断:新建订单时查产品的库存/生产周期信息,有货直接进入"待发货"状态,无货则进入"待评审"状态
评审流程:设计OrderReviewRecord记录每次评审的部门、评审人、意见,配合状态机推进订单在流程图各节点间流转
思路不复杂,但每往前走一步都会牵连出一堆之前没注意到的细节问题。

踩坑清单

  1. SDK版本的坑,昨天的老朋友又回来了
    项目pom.xml指定Java 17,但这次IDEA又用回了JDK 26默认SDK,Lombok注解处理器直接崩了:
    java: java.lang.UnsupportedOperationException: This feature requires ASM9
    和Day1的TypeTag :: UNKNOWN是同一类问题的不同报错形式——本质都是Lombok还没跟上最新JDK的字节码变化。解决方式一样:File → Project Structure → SDK,切回JDK 17。
    教训:这个问题不是一次性解决的,换新项目、换新窗口都可能因为IDEA默认SDK设置重新踩一遍。以后新建/打开项目第一件事就是检查SDK版本对不对。

  2. 实体类字段缺失
    Service层代码写好了setStatus()、getPrice()这些调用,编译器却说找不到方法——回头一看,OrderItem没有status字段(标记库存状态),ProductionCycle也没有price字段(算订单金额要用)。Day1设计表结构的时候只照着截图上的表格字段建的,没预留业务逻辑需要的辅助字段。
    解决:把缺的字段(status用String,price用BigDecimal)补进两个实体类。
    教训:先写Service层业务逻辑草稿,倒推需要实体类补充哪些字段,比先建表再写逻辑更不容易漏。

  3. 枚举值对不上
    Service里写了OrderStatus.REVIEW_PASSED,但Day1定义的枚举里压根没这个值,只有语义相近的CONFIRMED。
    解决:为了跟流程图节点命名对齐,在枚举里新增了REVIEW_PASSED,而不是将就用CONFIRMED顶替。
    教训:状态值的命名最好在开工前统一定好一份对照表(哪个状态对应流程图哪个节点),别写到哪算到哪,不然枚举会越加越乱。

  4. Service层方法"占位没实现"
    Controller里调用了listAll()、listByStatus()、getById(),但Day1的Service层其实只写了createOrder()一个方法——之前光顾着验证"能不能建一个订单",其他接口方法只在Controller里写了调用,Service这边压根没实现。
    java
    public List listAll() {
    return salesOrderRepository.findAll();
    }

public List listByStatus(OrderStatus status) {
return salesOrderRepository.findByStatus(status);
}

public SalesOrder getById(Long id) {
return salesOrderRepository.findById(id).orElse(null);
}

教训:Controller和Service的接口最好先对一遍,别让Controller"抢跑"写了调用,Service却没跟上。

  1. Repository泛型参数类型错的坑
    ProductionCycleRepository继承JpaRepository<ProductionCycle, Long>,但ProductionCycle的主键productCode其实是String类型(产品代码本来就是"A"/"B"/"C"这种字符串,不是自增数字)。Spring Data JPA启动时会校验泛型参数和实体@Id字段类型是否一致,对不上直接启动失败。
    解决:把泛型第二个参数改成String:
    java
    public interface ProductionCycleRepository extends JpaRepository<ProductionCycle, String> {
    ProductionCycle findByProductCode(String productCode);
    }
    教训:这类问题在写Repository的当下很容易忽略,因为它不是编译错误,是运行时启动检查才暴露,排查成本比编译错误更高。以后写Repository时第一反应就是回去看一眼对应实体的@Id到底是什么类型。

  2. data.sql跟实体字段"各说各话"
    Day1的data.sql插入语句用的列名是design_weeks、procurement_weeks这些(跟着试卷截图里的生产周期表字段走的),但今天给ProductionCycle新增字段之后,实体里其实还多了price、stock_quantity这些列,两边完全没对齐,SQL执行报"列不存在"。
    解决:重写data.sql,确保列名和实体的@Column注解完全一致:
    sql
    INSERT INTO production_cycle (product_code, cycle_a, cycle_b, cycle_c, stock_quantity, price)
    VALUES ('A', 2, 3, 4, 100, 75.00);
    教训:data.sql这种静态初始化脚本很容易被遗忘同步——改了实体字段之后,一定要回头检查预置数据脚本有没有跟着更新。

  3. application.properties又双叒被误覆盖了一次
    调试过程中手一抖,把curl测试命令粘贴进了配置文件,把数据库连接配置整个覆盖掉了,项目启动直接报连不上数据库。这已经是这两天第二次栽在这个坑上了。
    解决:从IDEA的本地历史(Local History)功能里翻出误操作前的版本恢复回来。
    教训:以后改配置文件前,习惯性先在其他地方(哪怕是记事本)备份一份,或者干脆把项目纳入Git管理,改坏了随时能git diff/git checkout找回来——这比每次手动恢复靠谱得多,Day3开始必须把Git用起来了。

  4. PowerShell里的curl陷阱,昨天记的笔记今天又用上了
    同样的坑——PowerShell里curl是Invoke-WebRequest的别名,得用curl.exe才是真的curl。这次多踩了一个新坑:用相对路径-d @test.json读取JSON文件时,PowerShell的当前工作目录和预期不一致,导致找不到文件,改成绝对路径才解决。
    教训:Windows下测接口,要么老老实实用curl.exe+绝对路径,要么直接换成Postman这类专门的图形化工具,能省掉很多这种平台差异带来的意外。

今天的成果
一上午鏖战下来,总算是啃下来了:
创建订单接口能正常返回201 Created,自动生成订单号(格式类似ORD-20260818-0001)
有库存时订单状态正确落在WAITING_FOR_SHIPMENT(待发货),无库存时落在PENDING_REVIEW(待评审)
查询全部订单、按状态筛选订单的接口都验证通过
美中不足的是,因为本地MySQL服务今天启动不了(又是一个新坑,还在排查具体原因),最后是切到H2内存数据库跑通的功能验证,代码逻辑没问题,但数据库连接这块还得回头补上。

经验总结
把这两天连起来看,几条心得越来越清晰:
环境先行:业务代码写得再好,JDK版本、构建工具、数据库连接这些基础设施但凡有一个没打通,后面全是在还债。
实体和Service要同步演进:每加一个业务字段,第一时间回头检查所有引用它的地方是否需要跟着改,包括容易被忽略的data.sql。
状态值要提前规划好,别写到哪个状态就临时加一个enum值,容易越加越乱,最好一开始就照着流程图把所有节点名称定死。
配置文件要么备份要么用Git,光靠"小心点"是不够的,这两天已经两次栽在同一个坑上了。
摸清自己的终端环境,PowerShell和CMD、Linux差异不小,测试API这种高频操作最好换成专门工具,别死磕命令行细节。
Day3预告

接下来要做订单变更/急插单流程(对应试卷5.4、5.5条)——变更后订单要能自动打回评审状态,触发相关部门重新审批;还要把发货和交付跟踪的接口补上。有了这两天的教训,Day3开工前会先把Git仓库建起来,再动手写代码,希望能少踩几个重复的坑。

posted on 2026-08-18 13:33  chenyun_922  阅读(7)  评论(0)    收藏  举报