慕斯3111050
2020-03-18 12:24
老师,按照教程,我在代码中,在insertFill和updateFill中都对要自动填充的字段进行了判断如下
@Override
public void insertFill(MetaObject metaObject) {
if (metaObject.hasSetter("createTime")) {
log.info("自动插入");
LocalDateTime current = LocalDateTime.now();
this.setInsertFieldValByName("createTime", current, metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
if (metaObject.hasSetter("updateTime")) {
log.info("自动更新字段");
LocalDateTime current = LocalDateTime.now();
this.setUpdateFieldValByName("updateTime", current, metaObject);
}
}经过debug发现,metaObject.hasSetter在insert时,底层调用的是BeanWrapper.hasSetter的方法,能判断是否包含了要设置的字段。
但是在update时,底层调用的是MapWrapper.hasSetter方法,这个方法直接返回true,并不判断是否包含要设置的字段,导致自动metaObject.hasSetter的判断不起作用,如下是debug截图。

我使用的mp版本是3.2.0。更新时调用的方法是updateById,不明白为什么在更新时没有调用BeanWrapper方法,而是调用MapWrapper
同学,你使用3.3.1.tmp版本试试,看看好不好使,我使用这个版本,debug时,看着调用的是BeanWrapper。
Object time = getFieldValByName("createTime", metaObject);和
Object time = getFieldValByName("updateTime", metaObject);在用法上没有区别,是可以使用的
老铁,你说的没错,可能这是官方的bug吧,我首先debug了
boolean updateTime = metaObject.hasSetter("updateTime");发现走的是MapWrapper.class中的代码:
public boolean hasSetter(String name) {
return true;
}直接返回的就是true,而debug以下代码的时候:
boolean createTime = metaObject.hasSetter("createTime");发现走的是BeanWrapper.class中的代码:
public boolean hasSetter(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
…………
} else {
return this.metaClass.hasSetter(name);
}
}所以添加
@TableField(fill = FieldFill.INSERT)
和
@TableField(fill = FieldFill.UPDATE)
他们走的判断路径都不一样
你的实体类上的注解是不是没有
@TableField(fill = FieldFill.INSERT_UPDATE ) private Date time;
你如果就是insert肯定没用啊
MyBatis-Plus进阶
23494 学习 · 118 问题
相似问题