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

2019-05-19  本文已影响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
上一篇 下一篇

猜你喜欢

热点阅读