配置好mybatis plus的自动填充时间后,进行更新操作时出现了以下异常:
org.springframework.dao.DataIntegrityViolationException:
### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Column 'gmt_modified' cannot be null
### The error may exist in com/ylz/druglist/dao/DrugNameReplaceDao.java (best guess)
### The error may involve com.ylz.druglist.dao.DrugNameReplaceDao.updateById-Inline
### The error occurred while setting parameters
### SQL: UPDATE drug_name_replace SET original_value=?, replace_value=?, operator_ip=?, gmt_modified=? WHERE id=? AND deleted=0
### Cause: java.sql.SQLIntegrityConstraintViolationException: Column 'gmt_modified' cannot be null
; Column 'gmt_modified' cannot be null; nested exception is java.sql.SQLIntegrityConstraintViolationException: Column 'gmt_modified' cannot be null
异常的信息为:进行更新的时候,gmt_modified 字段为空,无法进行修改操作。
对于mybatis plus的自动填充时间配置过程如下:
配置实体类:
@Data
@TableName(value = "drug_name_replace")
public class DrugNameReplaceDO {
@TableId(type = IdType.AUTO)
private Integer id;
private String originalValue;
private String replaceValue;
private String operatorIp;
@Version
private Integer version;
@TableLogic
private Integer deleted;
@TableField(value = "gmt_create", fill = FieldFill.INSERT)
private Date gmtCreate;
@TableField(value = "gmt_modified", fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
}
时间填充处理器如下
@Component
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
private final String GMT_CREATE = "gmt_create";
private final String GMT_MODIFIED = "gmt_modified";
@Override
public void insertFill(MetaObject metaObject) {
Date date = new Date();
this.setFieldValByName(GMT_CREATE, date, metaObject);
this.setFieldValByName(GMT_MODIFIED, date, metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
Date date = new Date();
this.setFieldValByName(GMT_MODIFIED, date, metaObject);
}
}
执行更新的操作代码如下:
DrugNameReplaceDO drugNameReplaceDO = new DrugNameReplaceDO();
drugNameReplaceDO.setId(1);
drugNameReplaceDO.setOriginalValue("甲");
drugNameReplaceDO.setReplaceValue("乙");
drugNameReplaceDO.setOperatorIp("123456789");
int i = drugNameReplaceDao.updateById(drugNameReplaceDO);
再三检查之后确认自己的代码是没有出错的,而且在处理器中进行日志记录发现传入的也是有数据的。
后面经过debug检查,在这段代码中发现
public boolean hasSetter(String propertyName) {
return this.setMethods.containsKey(propertyName);
}
代码在检查是否实体类中有该属性的setter方法的判断中,获取到的实体类的属性如下
其中对应的修改时间字段为 gmtModifired 。
而我传入的时间修改字段名称为
在该判断逻辑中,系统认为我没有传入对应时间修改的字段,从而在该设置值的代码中直接跳过了设置值的代码
default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
if (Objects.nonNull(fieldVal) && metaObject.hasSetter(fieldName)) {
metaObject.setValue(fieldName, fieldVal);
}
return this;
}
由于 metaObject.hasSetter(fieldName) 为false,所以跳过了 metaObject.setValue(fieldName, fieldVal);导致我设置的值。
所以只需要修改传入修改时间对应的字段就可以了。
将新增时间和修改时间对应的字段修改为驼峰形式,如下
private final String GMT_CREATE = "gmtCreate";
private final String GMT_MODIFIED = "gmtModified";
重新运行测试代码,测试成功。