记一次奇怪的DataIntegrityViolationException异常处理

记一次奇怪的DataIntegrityViolationException异常处理

梦开始的地方

​ 最近开发的时候出现了一次DataIntegrityViolationException异常,当时我也没太在意,因为开发里出现一个小小的bug也是正常的,于是我就开始百度,然后我就发现了事情的不对劲。因为百度出来的这个都是说是在更新数据库时出现的异常,但是我其实是做的查询操作。

​ 先说一下用到的框架,是SpringBoot+Mybatis,当时是需要做一个数据统计。结构大概如下:

  1. VO,num1和num2分别表示统计的两个数量,date就是统计时间,别在意我的命名,这里只是写的例子,我不可能直接把公司的代码贴出来吧,所以例子略显潦草。
@Data
@AllArgsConstructor
public class StatisticsVo {
    private Integer num1;
    private Integer num2;
    private Date date;
}
  1. Mapper,接口里是获取统计数据的方法
@Mapper
public interface StatisticsMapper {
    List<StatisticsVo> getData(@Param("startTime") Date startTime,@Param("endTime") Date endTime);
}
  1. StatisticsMapper.xml,这里我也简化一下,注意这里的date我其实是返回的统计开始时间,并不是数据库里的字段,因为这是统计里的一个特殊需求,否则我当时也不会出现这个错误。
<resultMap id="resultStatisticsVo" type="com.test.vo.StatisticsVo">
    <result property="num1" column="num1"/>
    <result property="num2" column="num2"/>
    <result property="date" column="date"/>
resultMap>
<select id="getData" resultMap="resultStatisticsVo">
    select num1,num2,#{startTime} as date from test_table
    where statistics_time between #{startTime} and #{endtTime} and ...
select>
  1. 错误信息,图里的2021-03-03 00:00:00就是我的统计开始时间。

记一次奇怪的DataIntegrityViolationException异常处理_第1张图片

找问题的过程

  1. 遇事不决先百度,额。。。根本就不是我想要的答案!

记一次奇怪的DataIntegrityViolationException异常处理_第2张图片

  1. 看错误信息,发现提示无法确定2021-03-03 00:00:00的值类型,但是我看数据类型都是Date呀,而且日志里看到的数据格式也是yyyy-MM-dd HH:mm:ss。于是把date的数据类型给改成String测试一下,结果还是报错,看来就不是数据类型转换方面的问题了。
@Data
@AllArgsConstructor
public class StatisticsVo {
    private Integer num1;
    private Integer num2;
    private String date;
}
  1. 抱着试试不怀孕的想法,我把date的取值改成了数据库里的字段statistics_time,然后居然没报错了,但是这根本不是我要的结果呀,我本来只想要我的统计开始时间作为date。
<resultMap id="resultStatisticsVo" type="com.test.vo.StatisticsVo">
    <result property="num1" column="num1"/>
    <result property="num2" column="num2"/>
    <result property="date" column="date"/>
resultMap>
<select id="getData" resultMap="resultStatisticsVo">
    select num1,num2,statistics_time as date from test_table
    where statistics_time between #{startTime} and #{endtTime} and ...
select>
  1. 后来我又再搞了半个小时,发现我忘记加无参构造了,然后我加上之后,腰也不酸了,腿也不痛了,问题解决了???
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StatisticsVo {
    private Integer num1;
    private Integer num2;
    private String date;
}

分析原因

​ 首先问题肯定不是我sql写错了,毕竟我拿出来在数据库里运行过,没报错,能查出正确的数据。然后我取到了数据,mybatis肯定会映射到对应的类中,而我采用的是标签,逐一定义数据库列名和对象属性名之间的映射关系,这一点我也检查过,没写错。再然后我是使用了@NoArgsConstructor注解添加了无参构造后才没出错的,这让我想到了Spring底层会调用Bean类的无参构造器来创建实例,因此要求该Bean提供无参的构造器。所以。。。所以为什么会报DataIntegrityViolationException的异常呀???这之间有啥的关系呀???而且为什么我用数据库里的字段statistics_time它就不会报错呀???

​ 在程序员的世界里,菜就是原罪呀。T_T

记一次奇怪的DataIntegrityViolationException异常处理_第3张图片

​ 虽然问题解决了,但是具体原理我还是不知道,有没有大佬能解答一下,请在评论区留下你的高见,或者猜想也行,大家一起讨论一下。

你可能感兴趣的:(Java)