baomidou / mybatis-plus

An powerful enhanced toolkit of MyBatis for simplify development
https://baomidou.com
Apache License 2.0
16.35k stars 4.31k forks source link

升级到3.5.1之后枚举类定义失败 #4338

Closed CaseCy closed 1 year ago

CaseCy commented 2 years ago

当前使用版本(必填,否则不予处理)

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>

jdk17,springboot2.5.5

该问题是如何引起的?(确定最新版也有问题再提!!!)

3.4.3(jdk11)的时候没问题,没有做任何修改,升到3.5.1(jdk17或11)之后就有这个问题了 配置文件里也配置了type-enums-package 对应枚举类上加了@EnumValue注解 对应枚举类

@Getter
public enum StepStatus {
    COMPLETE(1 "已完成"),
    ERROR(2, "错误"),
    DELETE(3, "已删除"),
    ;

    @EnumValue
    @JsonValue
    private final int code;
    private final String desc;

    StepStatus(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
}

重现步骤(如果有就写完整)

从2.4.3升到2.5.1

报错信息

Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'state' from result set.  Cause: java.lang.IllegalArgumentException: No enum constant modules.enums.StepStatus.1
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:87)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getPropertyMappingValue(DefaultResultSetHandler.java:512)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyPropertyMappings(DefaultResultSetHandler.java:481)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:405)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:355)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:329)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:302)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:195)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
    at jdk.internal.reflect.GeneratedMethodAccessor165.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:64)
    at jdk.proxy2/jdk.proxy2.$Proxy141.query(Unknown Source)
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
    at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:81)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
    at jdk.proxy2/jdk.proxy2.$Proxy140.query(Unknown Source)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
    at jdk.internal.reflect.GeneratedMethodAccessor175.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
    ... 26 common frames omitted
Caused by: java.lang.IllegalArgumentException: No enum constant modules.enums.StepStatus.1
    at java.base/java.lang.Enum.valueOf(Enum.java:273)
    at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:49)
    at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:26)
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
    ... 54 common frames omitted
yhl452493373 commented 2 years ago

同问题+1,退回3.5.0正常

nancheung commented 2 years ago

如何复现?什么场景下发生的问题?

yhl452493373 commented 2 years ago

如何复现?什么场景下发生的问题?

在Mapper.java对应的Mapper.xml文件里面的查询中,引用一个枚举值。

枚举:

public enum CoordinateType implements BaseEnum<Integer> {
    GPS("GPS", 3),
    BMAP("百度", 2),
    AMAP("高德", 1);

    private final String name;

    private final Integer code;

    CoordinateType(String name, Integer code) {
        this.name = name;
        this.code = code;
    }

    @Override
    public Integer getValue() {
        return code;
    }

    @Override
    public String getName() {
        return name;
    }

    public static CoordinateType ofName(String name) {
        return BaseEnum.ofName(CoordinateType.class, name);
    }

    public static CoordinateType ofValue(Integer value) {
        return BaseEnum.ofValue(CoordinateType.class, value);
    }
}

Mapper.java对应的Mapper.xml里面查询方法对应的sql

     SELECT ${@com.demo.enums.CoordinateType@BMAP.value} AS coordinate_type FROM demo_enums

以上写法,3.5.0及以下不报错,3.5.1报错

CaseCy commented 2 years ago

如何复现?什么场景下发生的问题?

demo地址:https://gitee.com/cononyc/mp-demo 版本改为3.4.3之后执行正常 建表语句

CREATE TABLE `sys_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `email` varchar(64) DEFAULT NULL,
  `mobile` varchar(64) DEFAULT NULL,
  `nick_name` varchar(64) DEFAULT NULL,
  `user_type` int(3) DEFAULT NULL,
  `state` int(2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

插入一条数据

INSERT INTO`sys_user`(`id`, `email`, `mobile`, `nick_name`, `user_type`, `state`) VALUES (1, 'fasdf', 'fasdf', 'fasd', 1, 2);

枚举值

@Getter
public enum UserState {
    ENABLE(1, "可用"),
    DISABLE(2, "禁用"),
    ;

    @EnumValue
    @JsonValue
    private final Integer code;
    private final String desc;

    UserState(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }
}
@Getter
public enum UserType {
    ADMIN(1, "管理员"),
    USER(2, "普通用户"),
    ;

    @EnumValue
    @JsonValue
    private final Integer code;
    private final String desc;

    UserType(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }
}

配置

mybatis-plus:
  type-enums-package: demo.modules.enums

entity定义

/**
 * @TableName sys_user
 */
@TableName(value = "sys_user")
@Data
public class SysUser implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 手机号
     */
    private String mobile;

    /**
     * 昵称
     */
    private String nickName;

    private UserType userType;

    private UserState state;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

mapper

@Repository
public interface SysUserMapper extends BaseMapper<SysUser> {

    List<SysUser> findByUserId(@Param("id") Long id);
}

xml

<?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="demo.modules.mapper.SysUserMapper">

    <resultMap id="BaseResultMap" type="demo.modules.entity.SysUser">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="email" column="email" jdbcType="VARCHAR"/>
            <result property="mobile" column="mobile" jdbcType="VARCHAR"/>
            <result property="nickName" column="nick_name" jdbcType="VARCHAR"/>
            <result property="userType" column="user_type" jdbcType="VARCHAR"/>
            <result property="state" column="state" jdbcType="TINYINT"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,email,mobile,
        nick_name,user_type,state
    </sql>
    <select id="findByUserId" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from sys_user
        where id = #{id}
    </select>
</mapper>

测试(数据库mysql 5.7.32)

@SpringBootTest
public class ProjectTest {
    @Resource
    private SysUserMapper sysUserMapper;

    @Test
    public void test1() {
        List<SysUser> steps = sysUserMapper.findByUserId(1L);
        System.out.println(steps);
    }
}
yhl452493373 commented 2 years ago

3.5.0也正常,就3.5.1有问题

lesons commented 2 years ago

3.5.0也正常,就3.5.1有问题

对的3.5.0枚举类型正常,今天升3.5.1就出问题了 都是一样的问题

FENGLINGZMB commented 2 years ago

我也遇到了类似的问题,枚举类作为实体类的属性,insert时可以正常插入数据,select时无法将取出的数据正确转化为枚举类。配置都没有问题,3.4.2正常工作,3.5.0和3.5.1会报错。

nancheung commented 2 years ago

感谢提供复现demo,已提交修复pr #4345

LucasZhanye commented 2 years ago

我也遇到了,一直倒退版本到3.4.2才正常,3.4.3,3.5.0和3.5.2都是报错!!!貌似没有修复?

qmdx commented 1 year ago
<result property="userType" column="user_type" jdbcType="VARCHAR"/>

这个返回类型映射 写错了

zzy129 commented 1 year ago

druid版本问题 要升级到1.2.0以上

huayanYu commented 1 year ago

升级DRUID

cctyl commented 11 months ago

druid版本问题 要升级到1.2.0以上

没有使用德鲁伊也出现了