# 诊断 MyBatis-Plus 自动填充问题 ## 问题现象 尽管 `MybastisColumnsHandler` 已经实现并配置了自动填充功能,但 `create_by` 和 `create_time` 字段仍然没有被正确填充。 ## 可能的原因及解决方案 ### 1. 检查组件扫描配置 确保 `MybastisColumnsHandler` 类被Spring容器正确管理: ```java @Component // 确保这个注解存在 public class MybastisColumnsHandler implements MetaObjectHandler { // ... } ``` ### 2. 检查包扫描路径 在主应用类中确保扫描到了处理器所在的包: ```java @SpringBootApplication @MapperScan("com.openhis.*.mapper") // 确保扫描到你的mapper @ComponentScan(basePackages = {"com.core", "com.openhis"}) // 确保扫描到处理器 public class OpenHisApplication { public static void main(String[] args) { SpringApplication.run(OpenHisApplication.class, args); } } ``` ### 3. 验证实体类配置 确保实体类正确继承了 `HisBaseEntity` 并且字段上有正确的注解: ```java @Data @TableName("adm_practitioner") public class Practitioner extends HisBaseEntity { // 不需要在子类中重复定义 createBy, createTime 等字段 // 因为它们已在 HisBaseEntity 中定义并带有 @TableField(fill = FieldFill.INSERT) } ``` ### 4. 检查安全上下文 自动填充处理器依赖于安全上下文来获取当前用户。确保在执行保存操作时用户已登录: ```java // 在保存之前,确保用户已登录 LoginUser loginUser = SecurityUtils.getLoginUser(); if (loginUser == null) { // 用户未登录,可能需要手动设置审计字段 } ``` ### 5. 手动测试自动填充 创建一个简单的测试来验证自动填充是否正常工作: ```java @SpringBootTest public class AutoFillTest { @Autowired private PractitionerMapper practitionerMapper; @Test public void testAutoFill() { Practitioner practitioner = new Practitioner(); practitioner.setName("Test Practitioner"); // 检查在保存前字段是否为空 System.out.println("Before insert - createBy: " + practitioner.getCreateBy()); System.out.println("Before insert - createTime: " + practitioner.getCreateTime()); // 执行插入操作 int result = practitionerMapper.insert(practitioner); // 检查保存后字段是否被填充 System.out.println("After insert - createBy: " + practitioner.getCreateBy()); System.out.println("After insert - createTime: " + practitioner.getCreateTime()); assertThat(result).isEqualTo(1); assertThat(practitioner.getCreateBy()).isNotNull(); assertThat(practitioner.getCreateTime()).isNotNull(); } } ``` ### 6. 临时解决方案 如果自动填充仍然不工作,可以在服务层手动设置这些字段: ```java @Service public class PractitionerServiceImpl extends ServiceImpl implements IPractitionerService { @Override public void savePractitioner(Practitioner practitioner) { // 手动设置审计字段 if (practitioner.getCreateBy() == null || practitioner.getCreateBy().isEmpty()) { LoginUser loginUser = SecurityUtils.getLoginUser(); if (loginUser != null) { practitioner.setCreateBy(loginUser.getUsername()); } else { practitioner.setCreateBy("system"); // 默认值 } } if (practitioner.getCreateTime() == null) { practitioner.setCreateTime(new Date()); } // 执行保存操作 this.save(practitioner); } } ``` ### 7. 检查 MyBatis-Plus 版本兼容性 确保使用的 MyBatis-Plus 版本与自动填充功能兼容。当前项目使用的是 3.5.5 版本,应该支持自动填充功能。 ### 8. 调试自动填充处理器 在 `MybastisColumnsHandler` 中添加日志来调试是否被调用: ```java @Override public void insertFill(MetaObject metaObject) { System.out.println("MybastisColumnsHandler.insertFill() called"); // 调试日志 Date currentTime = new Date(); this.strictInsertFill(metaObject, "createTime", Date.class, currentTime); this.strictInsertFill(metaObject, "create_time", Date.class, currentTime); String username = getCurrentUsername(); System.out.println("Setting createBy to: " + username); // 调试日志 this.strictInsertFill(metaObject, "createBy", String.class, username); this.strictInsertFill(metaObject, "create_by", String.class, username); // ... 其他代码 } ``` 通过以上步骤,应该能够诊断并解决自动填充不工作的问题。