美文网首页
mybatis使用基础类型进行实体映射的异常问题

mybatis使用基础类型进行实体映射的异常问题

作者: 鹅鹅鹅_ | 来源:发表于2019-05-19 12:38 被阅读0次

    先上此类问题可能出现的异常信息

    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
    ### Error querying database.  Cause: java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
    ### The error may exist in com/eee/account/dao/UserMapper.java (best guess)
    ### The error may involve com.eee.account.dao.UserMapper.selectByPrimaryKey
    ### The error occurred while handling results
    ### SQL: SELECT id,name,bio,email,phone,create_time,is_actived  FROM user  WHERE  id = ?
    ### Cause: java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
    

    OR

    org.springframework.dao.DataIntegrityViolationException: Error attempting to get column 'PUBLISH_TIME' from result set.  Cause: org.h2.jdbc.JdbcSQLDataException: Data conversion error converting "2028-12-16 17:13:09.742" [22018-199]
    ; Data conversion error converting "2028-12-16 17:13:09.742" [22018-199]; nested exception is org.h2.jdbc.JdbcSQLDataException: Data conversion error converting "2028-12-16 17:13:09.742" [22018-199]
    

    我在Springboot中使用kt-mybatis进行了通用mapper映射。如下为sql建表语句,重点关注type字段

    CREATE TABLE `user` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `name` varchar(64) default NULL COMMENT '名字',
      `bio` varchar(64) default NULL COMMENT '简介',
      `email` varchar(64) DEFAULT NULL COMMENT '邮箱',
      `phone` varchar(13) DEFAULT NULL COMMENT '手机号',
      `create_time` DATETIME default CURRENT_TIMESTAMP COMMENT '创建时间',
      `type` INT default NULL COMMENT '测试',
      `is_actived` BOOLEAN default true COMMENT '是否激活',
    
      PRIMARY KEY (`id`),
      UNIQUE user_email_unique(email),
      UNIQUE user_phone_unique(phone)
    ) ENGINE=InnoDB;
    

    实体映射类

    package com.eee.account.domain;
    
    import lombok.Builder;
    import lombok.Data;
    import tk.mybatis.mapper.annotation.KeySql;
    
    import javax.persistence.Column;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import java.util.Date;
    
    @Data
    @Builder
    @Table(name = "user")
    public class User {
        @Id
        @KeySql(useGeneratedKeys = true)
        private Long id;
    
        private String name;
    
        private String bio;
    
        private String email;
    
        private String phone;
    
        private Date createTime;
    
        @Column(name = "is_actived")
        private boolean actived;
    
        private int type;
    }
    

    insert和select执行日志

    2019-05-19 12:02:38.051 [main] DEBUG com.eee.account.dao.UserMapper.insert -
                    ==>  Preparing: INSERT INTO user ( id,name,bio,email,phone,create_time,is_actived ) VALUES( ?,?,?,?,?,?,? ) 
    2019-05-19 12:02:38.066 [main] DEBUG com.eee.account.dao.UserMapper.insert -
                    ==> Parameters: null, WzJhqYdRi(String), syobTnpHoRk(String), enMaXjdZnGVx(String), DLtldvmFemD(String), 2021-10-21 21:06:03.9(Timestamp), true(Boolean)
    2019-05-19 12:02:38.070 [main] DEBUG com.eee.account.dao.UserMapper.insert -
                    <==    Updates: 1
    2019-05-19 12:02:38.077 [main] DEBUG com.eee.account.dao.UserMapper.insert -
                    ==>  Preparing: INSERT INTO user ( id,name,bio,email,phone,create_time,is_actived ) VALUES( ?,?,?,?,?,?,? ) 
    2019-05-19 12:02:38.077 [main] DEBUG com.eee.account.dao.UserMapper.insert -
                    ==> Parameters: null, SHcBlCvBt(String), rPCPMcOYfRD(String), evKZtGVeB(String), lfnEtVE(String), 2025-08-17 10:33:10.574(Timestamp), true(Boolean)
    2019-05-19 12:02:38.078 [main] DEBUG com.eee.account.dao.UserMapper.insert -
                    <==    Updates: 1
    2019-05-19 12:02:38.083 [main] DEBUG com.eee.account.dao.UserMapper.selectByPrimaryKey -
                    ==>  Preparing: SELECT id,name,bio,email,phone,create_time,is_actived FROM user WHERE id = ? 
    2019-05-19 12:02:38.084 [main] DEBUG com.eee.account.dao.UserMapper.selectByPrimaryKey -
                    ==> Parameters: 2(Long)
    2019-05-19 12:02:38.101 [main] DEBUG com.eee.account.dao.UserMapper.deleteByPrimaryKey -
                    ==>  Preparing: DELETE FROM user WHERE id = ? 
    2019-05-19 12:02:38.102 [main] DEBUG com.eee.account.dao.UserMapper.deleteByPrimaryKey -
                    ==> Parameters: 1(Long)
    2019-05-19 12:02:38.105 [main] DEBUG com.eee.account.dao.UserMapper.deleteByPrimaryKey -
                    <==    Updates: 1
    

    从日志可以看到,insert和select语句竟然忽略了type类型的存在,查看表结构,type确实是建在表中了,所以是实体类映射出问题了。

    我们再来看一下type相关的sql和实体类。因为我在配置文件配置了mapper.style=camelhump,所以名称映射转换应该是没问题的。

    # sql
    `type` INT default NULL COMMENT '测试',
    # 实体类字段
    private int type;
    

    经过一番调试,我发现是实体类映射,字段类型不支持是int long boolean double等基础类型,必须得是对应的Java封装类Integer Long Boolean Double。
    所以实体类type字段应该改为

    private Integer type;
    

    或者使用Column注解显示指定映射关系

    @Column(name = "type")
    private boolean type;
    

    后来找到了文档说明


    image.png

    这个问题貌似和TypeHandler有关


    image.png

    相关文章

      网友评论

          本文标题:mybatis使用基础类型进行实体映射的异常问题

          本文链接:https://www.haomeiwen.com/subject/jngfzqtx.html