copyProperties某个字段没有拷贝
问题
在使用 BeanUtils.copyProperties(oldData, newData)
进行对象拷贝时,发现 purchasedPrice
(采购价格)字段未被成功复制到新对象中,其他字段均正常拷贝。
核心原因:
表面定义 vs 实际运行时类型不一致
- Java 实体类定义:
Plain
private String purchasedPrice;
- 数据库字段类型:
Plain
purchased_price INT / BIGINT -- 实际存储为数值类型(如 7800)
由于 未配置 MyBatis-Plus 的类型处理器(TypeHandler),MyBatis-Plus 在执行查询时:
- 忽略 Java 字段的声明类型;
- 直接根据数据库列类型(
BIGINT
)将值映射为Long
(或Integer
); - 通过反射将
Long
值赋给声明为String
的字段(Java 编译期不报错,但运行时类型错误)。
结果:
oldData.purchasedPrice
实际类型是java.lang.Long
,而非String
。
Spring BeanUtils.copyProperties
的行为限制
Spring 提供的 BeanUtils.copyProperties(source, target)
仅支持相同类型的字段拷贝,不进行自动类型转换。
- 源字段类型:
Long
- 目标字段类型:
String
- → 类型不匹配,直接跳过该字段,不拷贝、不报错
- 验证方式
在调试或日志中添加以下代码验证:
Plain
FoodPurchasedInfo oldData = foodPurchasedInfoMapper.selectById(1);
System.out.println("purchasedPrice 值: " + oldData.getPurchasedPrice());
System.out.println("purchasedPrice 实际类型: " + oldData.getPurchasedPrice().getClass());
输出示例:
Plain
purchasedPrice 值: 7800
purchasedPrice 实际类型: class java.lang.Long
这证实了:字段值虽存在,但类型与声明不符,导致拷贝失败。
解决
将字段类型改为Long