问题
服务端orm的框架使用的是mybatis ,当insert管理员时,出现如下错误:
org.apache.ibatis.reflection.ReflectionException:
Could not set property 'id' of 'class com.xxx.Manager' with value '1407257724219068417' Cause:
java.lang.IllegalArgumentException: java.lang.ClassCastException@78c9c0fb
解释问题
上述问题解释成中文就是:无法将值1407257724219068417设置为类com.xxx.Manager的id属性值,是因为该值是非法参数。
什么情况会出现非法参数,可以举出如下的例子说明:
public class ClassLoaderCheck {
public static void main(String[] args) {
//毫秒时间戳格式
String timeStamp = "1658635894000";
//要转成后的时间格式
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 时间戳转换成时间
System.out.println(sdf.format(new Date(timeStampLong)));
}
}
可以看其输出结果为:
我们将上面毫秒字符串时间戳转为整型时间戳,如下所示:
public static void main(String[] args) {
//毫秒时间戳格式
String timeStamp = "1658635894000";
//parse成长整型
long timeStampLong = Long.parseLong(timeStamp);
//要转成后的时间格式
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 时间戳转换成时间
System.out.println(sdf.format(new Date(timeStampLong)));
}
再次输出,如图所示:
由此可以看出,报出java.lang.IllegalArgumentException
这个问题,一般情况下,就是输入的参数不符合方法的解析规则。
所以,我们可以沿着这条路,继续分析Could not set property 'id' of 'class com.xxx.Manager' with value '1407257724219068417'
这个问题。
分析问题
于是去排查managerMapper.xml
文件的insert语句
<insert id="insert" parameterType="com.xxx.Manager">
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID() AS id
</selectKey>
insert into manager (
name, xxx, updateTime
)
values (
#{name,jdbcType=VARCHAR},xxx, #{updateTime,jdbcType=TIMESTAMP}
)
</insert>
由于是通过selectKey
生成主键id的数值,此时,mybatis会在主键上生成其默认的uuid的值,比如上面的1407257724219068417
,而manager的主键为int的类型且最大长度为11,如图所示:
解决问题
UUID的字符长度超出了id的字符长度,所以,报出了上面的的错误,只要在主键id上注明TableId即可,如下所示:
@TableId(type = IdType.AUTO)
private Integer id;
当然IdType还有其他类型,我们来看看IdType的类型
值 | 描述 |
---|---|
Auto | 数据库自增 |
Input | 自行输入 |
ID_Worker | 分布式全局唯一ID 长整型类型 |
UUID | 32位UUID字符串 |
NONE | 无状态 |
ID_WORKER_STR | 分布式全局唯一ID 字符串类型 |
日拱一卒,功不唐捐