在写项目的时候发现某个表中的storemanageContract字段数据总是被更新,很是疑惑,发现更新时间是在凌晨,而项目中在凌晨中执行的代码只有定时器,于是去寻找相关代码,下面是我的代码模块。
@Scheduled(cron = "0 39 0 * * ?")
public void timer24h0039() {
List<SportStore> sportStores = sportStoreMapper.selectList(null);
//遍历所有商户
sportStores.stream().forEach(sportStore -> {
.....
JSONObject heatIndex90day = new JSONObject();
heatIndex90day.put("countQuickContract", countQuickContract);
heatIndex90day.put("countOfflineContract", countOfflineContract);
heatIndex90day.put("countMemberMoney", countMemberMoney);
heatIndex90day.put("countStoreLog", countStoreLog);
heatIndex90day.put("indexTotal", indexTotal);
heatIndex90day.put("indexUpdateTime", DemoUtils.getTime());
sportStore.setHeatIndex90day(heatIndex90day.toString());
sportStoreMapper.updateById(sportStore);
});
}
可以看到我这里是使用了mybatis-plus框架进行的,我确实没有设置storemanageContract字段的值,而我的实体类是这样子写的
/**
* (SportStore)表实体类
*
* @author makejava
* @since 2022-11-21 17:06:47
*/
@Data
@TableName("m_store")
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SportStore extends Model<SportStore> {
.....
@TableField(value = "storemanage_contract", typeHandler = StoremanageContractTypeHandler.class)
private GroupContract storemanageContract;
}
@Data
public class GroupContract {
//允许退款的天数,快捷、会员、商品、到家订单有效
private Integer storeAllowRefundDays;
//语音播报通知
private String socketclerkid;
private FacepayAllowed facepayAllowed;
private HomeContract homeContract;
private GoodsContract goodsContract;
private EquityContract equityContract;
private FoodContract foodContract;
private String storeName;
.....
}
这里我使用了自定义类TypeHandler,而TypeHandler写的内容是
@MappedTypes({GroupContract.class})
public class StoremanageContractTypeHandler extends MyAbstractTypeHandler<GroupContract> {
public StoremanageContractTypeHandler() {
this.type=GroupContract.class;
}
}
可以看到我就简单定义了一下,不知有没有大佬看出来问题,下面我就跟大家说一下是怎么一回事。
可以看到SportStore 实体类有一个 storemanageContract 字段,该字段使用了自定义的 TypeHandler StoremanageContractTypeHandler。这个 TypeHandler 用于处理 storemanageContract 字段与数据库之间的映射。
当执行定时任务并调用 sportStoreMapper.updateById(sportStore)时,MyBatis-Plus会尝试更新实体类的所有字段。由于 storemanageContract 字段是 GroupContract 类型的对象,且该对象的所有属性都是 null(如果在代码中没有显式地设置它们的值),TypeHandler 在处理这个字段时,会将其转换为一个所有属性都是 null 的JSON字符串。
解决方法:
- 编写自定义的方法来更新字段
- 在更新之前,确保对象的所有属性都被设置为正确的值。
- 检查 StoremanageContractTypeHandler 的实现,确保它正确处理了 null 值的情况。