省流侠:
实体类记得加上
@AllArgsConstructor
@NoArgsConstructor
问题出现
apifox接口文档事故现场
本来是在一次快乐的写api测试文档,准备了一些测试数据和调用顺序准备跑,然后突然
瞳 孔 地 震
然后只能被迫骑上♿开始debug
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
IDEA Console
org.springframework.dao.DataIntegrityViolationException:
Error attempting to get column 'biscuit_id' from result set.
Cause: java.sql.SQLDataException: Cannot determine value type from string '2a1Rr4cP'
; Cannot determine value type from string '2a1Rr4cP'
...
Caused by: java.sql.SQLDataException: Cannot determine value type from string '2a1Rr4cP'
...
Caused by: com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string '2a1Rr4cP'
情况说明
先提一嘴我的一些环境:
CREATE TABLE `nmb_biscuit` (
`user_id` int NOT NULL,
`biscuit_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`activate` int DEFAULT NULL,
`timestamp` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`biscuit_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/**
* @TableName nmb_biscuit
*/
@TableName(value ="nmb_biscuit")
@Data
@Builder
@ToString
public class Biscuit implements Serializable {
private Integer user_id;
@TableId
private String biscuit_id;
private Integer activate;
private LocalDateTime timestamp;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="icu.dbkx.opnmb.generator.mapper.BiscuitMapper">
<resultMap id="BaseResultMap" type="icu.dbkx.opnmb.generator.entity.Biscuit">
<id property="user_id" column="user_id" jdbcType="INTEGER"/>
<result property="biscuit_id" column="biscuit_id" jdbcType="VARCHAR"/>
<result property="activate" column="activate" jdbcType="INTEGER"/>
<result property="timestamp" column="timestamp" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
user_id,biscuit_id,activate,
timestamp
</sql>
</mapper>
在这里就能看到:entity里是string,mapper里和数据库里都是VARCHAR类型,理应没有任何问题
至少从正常的解决办法——即从类型错配的方面——来看是没法解决的
问题解决
mybatis报错Error attempting to get column ‘id‘ from result set. Cause: org.postgresql.util.PSQLExcept世上还是好人多啊
细细地看报错就会发现,数据从数据库出来的这一过程是没有问题的:
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@33b8c940] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@931617775 wrapping com.mysql.cj.jdbc.ConnectionImpl@7285c37b] will not be managed by Spring
==> Preparing: SELECT biscuit_id,user_id,activate,timestamp FROM nmb_biscuit WHERE (user_id = ? AND activate = ?)
==> Parameters: 106(Integer), 1(Integer)
<== Columns: biscuit_id, user_id, activate, timestamp
<== Row: 2a1Rr4cP, 106, 1, 2024-05-25 02:44:44
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@33b8c940]
但是console给了我们一个极不寻常的提示:
com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string '2a1Rr4cP'
以及:
Caused by: java.sql.SQLDataException: Cannot determine value type from string '2a1Rr4cP'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:115) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:98) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:90) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:64) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:74) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:96) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1431) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.result.ResultSetImpl.getInt(ResultSetImpl.java:830) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.mysql.cj.jdbc.result.ResultSetImpl.getInt(ResultSetImpl.java:851) ~[mysql-connector-j-8.0.33.jar:8.0.33]
at com.zaxxer.hikari.pool.HikariProxyResultSet.getInt(HikariProxyResultSet.java) ~[HikariCP-5.0.1.jar:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:68) ~[mybatis-3.5.13.jar:3.5.13]
at jdk.proxy3/jdk.proxy3.$Proxy127.getInt(Unknown Source) ~[na:na]
at org.apache.ibatis.type.IntegerTypeHandler.getNullableResult(IntegerTypeHandler.java:36) ~[mybatis-3.5.13.jar:3.5.13]
at org.apache.ibatis.type.IntegerTypeHandler.getNullableResult(IntegerTypeHandler.java:26) ~[mybatis-3.5.13.jar:3.5.13]
at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:86) ~[mybatis-3.5.13.jar:3.5.13]
mybatis尝试把一个String类型转换成Integer。
我们可以看到最后返回接收对象的结果类,是使用了构造函数来进行构造的,可是按照我们的对象类正常是无参构造才对,因为我们只用了@Data注解,正常情况是没有构造函数的,但是这里却走进了默认的构造函数。
在mybatis结果集映射中,因为受到构造函数的影响,造成了值的对应错误,同时notNull注解会更改构造函数的结构,处理方法我们可以增加@NoArgsConstructor 和@AllArgsConstructor变为有参和无参构造,但是请注意,这样会使notNull的单参数构造失效
给mybatisplus生成的domain里加上
@AllArgsConstructor
@NoArgsConstructor
后就正常了