Spring Data MongoDB在ApplicationRunner中无法写入数据但Controller可正常写入的问题求助
首先,我注意到你代码里有一个明显的逻辑错误,会导致仓库商品数据完全混乱:在创建merchandiseQuantity2到merchandiseQuantity6时,你一直用merchandiseQuantity1.put()来添加键值对,而不是对应的merchandiseQuantity2.put()、merchandiseQuantity3.put()等。比如:
Map<String, Integer> merchandiseQuantity2 = new HashMap<>(); merchandiseQuantity1.put("laptop", 100); // 这里应该是merchandiseQuantity2.put! merchandiseQuantity1.put("grivna", 20); merchandiseQuantity1.put("beer", 1);
这个错误会让所有Warehouse对象的merchandiseQuantity引用同一个HashMap实例,后续的put操作还会覆盖之前的数据,先把这个问题修正,避免数据逻辑混乱。
接下来针对ApplicationRunner无法写入数据但Controller可以的问题,我们来排查几个常见原因:
1. 实体类缺少无参构造函数
Spring Data MongoDB在持久化实体时,底层需要通过反射创建对象,这要求实体类必须有无参构造函数。而Controller中通过@RequestBody接收参数时,Jackson可以借助有参构造(配合@Data、@JsonProperty等注解)反序列化对象,所以不会出问题,但ApplicationRunner中直接创建对象保存时,如果实体类没有无参构造,就可能导致保存失败。
解决方案:
给Customer、Warehouse、Coordinate类添加无参构造函数,比如用Lombok的@NoArgsConstructor注解(如果已经用了@Data,默认包含无参构造,但如果手动写了有参构造,需要显式添加@NoArgsConstructor):
@Data @NoArgsConstructor @AllArgsConstructor public class Customer { private String name; private Coordinate coordinate; // 其他字段... }
2. 未捕获保存时的异常
ApplicationRunner的run()方法声明了抛出Exception,但Spring会捕获这些异常且可能不输出详细日志,导致你不知道保存操作是否出错。
解决方案:
在run()方法中添加try-catch块,打印异常信息,方便排查问题:
@Override public void run(ApplicationArguments args) throws Exception { try { // 你的创建和保存代码... customerRepository.save(customer1); // ...其他保存操作 System.out.println("数据写入完成"); } catch (Exception e) { System.err.println("写入数据时发生异常:"); e.printStackTrace(); } }
3. 使用批量保存替代逐个保存
逐个调用save()方法可能因多次IO操作出现不稳定情况,换成批量保存不仅效率更高,也更可靠:
// 批量保存Customer List<Customer> customers = Arrays.asList(customer1, customer2, customer3); customerRepository.saveAll(customers); // 批量保存Warehouse List<Warehouse> warehouses = Arrays.asList(warehouse1, warehouse2, warehouse3, warehouse4, warehouse5, warehouse6); warehouseRepository.saveAll(warehouses);
4. 检查事务上下文(可选)
虽然Spring Data MongoDB的save()默认不需要事务,但如果你的项目配置了事务管理,ApplicationRunner的run()方法默认不在事务上下文内,可能导致数据无法提交。可以尝试给run()方法添加@Transactional注解:
@Override @Transactional public void run(ApplicationArguments args) throws Exception { // 你的代码... }
优先修正map赋值错误和添加无参构造函数,再配合日志排查异常,应该能解决你的问题。
内容的提问来源于stack exchange,提问作者Mishamba

