Files
his/diagnose_autofill_issue.md

143 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 诊断 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<PractitionerMapper, Practitioner>
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);
// ... 其他代码
}
```
通过以上步骤,应该能够诊断并解决自动填充不工作的问题。