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;
后来找到了文档说明
![](https://img.haomeiwen.com/i14125002/d17de3918fe36d80.png)
这个问题貌似和TypeHandler有关
![](https://img.haomeiwen.com/i14125002/8b615f44d9d64996.png)