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

3.3.0

该问题是怎么引起的?**

QueryWrapper 使用enum类型的参数时,不能正确地根据MybatisEnumHandler转换。

重现步骤

public class TestModel {

    private Long companyId;

    private String companyName;

    private Boolean success;

    @TableField(typeHandler = MybatisEnumTypeHandler.class)
    private Status status;

    @AllArgsConstructor
    @Getter
    public enum Status {
        UNKNOWN(0, "未知"),
        SUCCESS(1, "成功"),
        FAILED(2, "失败");

        @EnumValue
        private final int value;

        private final String name;
    }

}

第一种使用方式:

TestModel testModel = new TestModel();
testModel.setStatus(TestModel.Status.SUCCESS);
LambdaQueryWrapper<TestModel> queryWrapper = new LambdaQueryWrapper<>(testModel);
int count = testMapper.selectCount(queryWrapper);

报错信息:

Caused by: java.lang.IllegalArgumentException: Could not find @EnumValue in Class: java.lang.Object.
    at com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler.lambda$null$0(MybatisEnumTypeHandler.java:65)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler.lambda$new$1(MybatisEnumTypeHandler.java:65)
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
    at com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler.<init>(MybatisEnumTypeHandler.java:64)
    ... 84 more

第二种使用方式:

LambdaQueryWrapper<TestModel> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(TestModel::getStatus, TestModel.Status.FAILED);
int countFailed = testModelRepo.getBaseMapper().selectCount(queryWrapper);
assertEquals(2, countFailed);

不能正确执行: debug信息:

2019-12-31 09:22:46,792 [Test worker] DEBUG c.i.s.v.t.m.T.selectCount - ==>  Preparing: SELECT COUNT( 1 ) FROM test_model WHERE (status = ?) 
2019-12-31 09:22:46,794 [Test worker] DEBUG c.i.s.v.t.m.T.selectCount - ==> Parameters: FAILED(String)
2019-12-31 09:22:46,823 [Test worker] DEBUG c.i.s.v.t.m.T.selectCount - <==      Total: 1
expected:<2> but was:<1>
Expected :2
Actual   :1

Comment From: miemieYaho

去看文档

Comment From: helloqhx

请问一下哪里配错了吗?除了需要配置@EnumValue外,还需要什么配置吗?

Comment From: bits-bean

这态度。。。好歹你也贴一下文档链接呀

Comment From: lihuagang03

建议提供完整的解决方法,说明问题根因,避免重复踩坑。

自动映射枚举 https://baomidou.com/guides/auto-convert-enum/

1755

2141

Could not find @EnumValue in Class: java.lang.Object.

Comment From: lihuagang03

按照官方文档,确实解决了

自动映射枚举 https://baomidou.com/guides/auto-convert-enum/

声明通用枚举属性 方式一:使用 @EnumValue 注解枚举属性

配置 MyBatis-Plus 自动映射枚举 方式二:全局修改 DefaultEnumTypeHandler

MyBatis-Plus Enum 类型在query时出错

MyBatis-Plus Enum 类型在query时出错

InterfaceCacheConfigDo

import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.lefit.gateway.admin.client.model.EnableStateEnum;
import com.lefit.gateway.admin.client.model.EnvironmentTagEnum;
import lombok.Data;

/**
 * 接口缓存配置【数据对象】
 *
 * @since 2024/5/17
 */
@Data
@TableName(value = "t_api_interface_cache_config", autoResultMap = true)
public class InterfaceCacheConfigDo {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    // ...

    /**
     * 环境标签,1-开发环境,2-测试环境,3-预发环境,4-生产环境
     */
    @TableField(value = "environment_tag")
    private EnvironmentTagEnum environmentTag;

    /**
     * 启用状态,0-未启用,1-启用
     */
    @TableField(value = "enable_status")
    private EnableStateEnum enableStatus;

    // ...

    /**
     * 创建时间
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

EnvironmentTagEnum

import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 环境标签
 *
 * @since 2024/5/17
 */
@Getter
@AllArgsConstructor
public enum EnvironmentTagEnum {
    /**
     * 开发环境
     */
    DEVELOP_ENV(0),
    /**
     * 测试环境
     */
    TEST_ENV(1),
    /**
     * 预发环境
     */
    STAGING_ENV(2),
    /**
     * 生产环境
     */
    PRODUCTION_ENV(3),
    ;

    /**
     * 标记数据库存的值是code
     */
    @EnumValue
    private final int code;
}

EnableStateEnum

import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 启用状态
 *
 * @since 2024/5/17
 */
@Getter
@AllArgsConstructor
public enum EnableStateEnum {
    /**
     * 未启用
     */
    NOT_ENABLE(0),
    /**
     * 启用
     */
    ENABLE(1),
    ;

    /**
     * 标记数据库存的值是code
     */
    @EnumValue
    private final int code;
}

application.properties

mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

Comment From: fengjian1993

按照官方文档,确实解决了

自动映射枚举 https://baomidou.com/guides/auto-convert-enum/

声明通用枚举属性 方式一:使用 @EnumValue 注解枚举属性

配置 MyBatis-Plus 自动映射枚举 方式二:全局修改 DefaultEnumTypeHandler

InterfaceCacheConfigDo

``` import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.lefit.gateway.admin.client.model.EnableStateEnum; import com.lefit.gateway.admin.client.model.EnvironmentTagEnum; import lombok.Data;

/ * 接口缓存配置【数据对象】 * * @since 2024/5/17 */ @Data @TableName(value = "t_api_interface_cache_config", autoResultMap = true) public class InterfaceCacheConfigDo { / * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Long id;

// ...

/**
 * 环境标签,1-开发环境,2-测试环境,3-预发环境,4-生产环境
 */
@TableField(value = "environment_tag")
private EnvironmentTagEnum environmentTag;

/**
 * 启用状态,0-未启用,1-启用
 */
@TableField(value = "enable_status")
private EnableStateEnum enableStatus;

// ...

/**
 * 创建时间
 */
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;

/**
 * 更新时间
 */
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

} ```

EnvironmentTagEnum

``` import com.baomidou.mybatisplus.annotation.EnumValue; import lombok.AllArgsConstructor; import lombok.Getter;

/ * 环境标签 * * @since 2024/5/17 */ @Getter @AllArgsConstructor public enum EnvironmentTagEnum { / * 开发环境 / DEVELOP_ENV(0), / * 测试环境 / TEST_ENV(1), / * 预发环境 */ STAGING_ENV(2), / * 生产环境 */ PRODUCTION_ENV(3), ;

/**
 * 标记数据库存的值是code
 */
@EnumValue
private final int code;

} ```

EnableStateEnum

``` import com.baomidou.mybatisplus.annotation.EnumValue; import lombok.AllArgsConstructor; import lombok.Getter;

/ * 启用状态 * * @since 2024/5/17 */ @Getter @AllArgsConstructor public enum EnableStateEnum { / * 未启用 / NOT_ENABLE(0), / * 启用 / ENABLE(1), ;

/**
 * 标记数据库存的值是code
 */
@EnumValue
private final int code;

} ```

application.properties

ini mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

你好这个参数mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler我没办法加,这个影响了所有的枚举类的TypeHander,不同的类存数据库的字段是不一样的,有写是code有些是value有些是name。 目前我在自己的枚举属性上加了@EnumValue, 实体类上加了TypeHandler,我的typeHandler构造方法报错Caused by: java.lang.IllegalArgumentException: Object does not represent an enum type. 还请赐教

Comment From: lihuagang03

你好这个参数mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler我没办法加,这个影响了所有的枚举类的TypeHander,不同的类存数据库的字段是不一样的,有写是code有些是value有些是name。 目前我在自己的枚举属性上加了@EnumValue, 实体类上加了TypeHandler,我的typeHandler构造方法报错Caused by: java.lang.IllegalArgumentException: Object does not represent an enum type. 还请赐教

  • 可以把你相关的完整代码,贴出来。
  • mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler,是Spring Boot自动化配置。可以通过MybatisConfiguration#setDefaultEnumTypeHandler手动设置喔
  • “不同的类存数据库的字段是不一样的,有写是code有些是value有些是name。” 属性字段的命名,没关系,可以任意取名。

Comment From: lihuagang03

你好这个参数mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler我没办法加,这个影响了所有的枚举类的TypeHander,不同的类存数据库的字段是不一样的,有写是code有些是value有些是name。 目前我在自己的枚举属性上加了@EnumValue, 实体类上加了TypeHandler,我的typeHandler构造方法报错Caused by: java.lang.IllegalArgumentException: Object does not represent an enum type. 还请赐教

  • "IllegalArgumentException: Object does not represent an enum type.",异常提示信息很明显了,字段定义的类型是枚举类型吗? 建议把相关代码贴出来,不然在抓瞎喔。提供的信息不够看清楚问题根因

Comment From: jcatom

按照官方文档,确实解决了

自动映射枚举 https://baomidou.com/guides/auto-convert-enum/

声明通用枚举属性 方式一:使用 @EnumValue 注解枚举属性

配置 MyBatis-Plus 自动映射枚举 方式二:全局修改 DefaultEnumTypeHandler

InterfaceCacheConfigDo

``` import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.lefit.gateway.admin.client.model.EnableStateEnum; import com.lefit.gateway.admin.client.model.EnvironmentTagEnum; import lombok.Data;

/ * 接口缓存配置【数据对象】 * * @since 2024/5/17 */ @Data @TableName(value = "t_api_interface_cache_config", autoResultMap = true) public class InterfaceCacheConfigDo { / * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Long id;

// ...

/**
 * 环境标签,1-开发环境,2-测试环境,3-预发环境,4-生产环境
 */
@TableField(value = "environment_tag")
private EnvironmentTagEnum environmentTag;

/**
 * 启用状态,0-未启用,1-启用
 */
@TableField(value = "enable_status")
private EnableStateEnum enableStatus;

// ...

/**
 * 创建时间
 */
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;

/**
 * 更新时间
 */
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

} ```

EnvironmentTagEnum

``` import com.baomidou.mybatisplus.annotation.EnumValue; import lombok.AllArgsConstructor; import lombok.Getter;

/ * 环境标签 * * @since 2024/5/17 */ @Getter @AllArgsConstructor public enum EnvironmentTagEnum { / * 开发环境 / DEVELOP_ENV(0), / * 测试环境 / TEST_ENV(1), / * 预发环境 */ STAGING_ENV(2), / * 生产环境 */ PRODUCTION_ENV(3), ;

/**
 * 标记数据库存的值是code
 */
@EnumValue
private final int code;

} ```

EnableStateEnum

``` import com.baomidou.mybatisplus.annotation.EnumValue; import lombok.AllArgsConstructor; import lombok.Getter;

/ * 启用状态 * * @since 2024/5/17 */ @Getter @AllArgsConstructor public enum EnableStateEnum { / * 未启用 / NOT_ENABLE(0), / * 启用 / ENABLE(1), ;

/**
 * 标记数据库存的值是code
 */
@EnumValue
private final int code;

} ```

application.properties

mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler这个配置是必要条件,实现IEnum接口或使用@EnumValue才是两种方式,当不配置全局default-enum-type-handler时,只在字段上添加typeHander=MybatisEnumTypeHandler.class就会出现楼主说的这种情况。

Comment From: lihuagang03

mybatis-plus.configuration.default-enum-type-handler=com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler这个配置是必要条件,实现IEnum接口或使用@EnumValue才是两种方式,当不配置全局default-enum-type-handler时,只在字段上添加typeHander=MybatisEnumTypeHandler.class就会出现楼主说的这种情况。

意思明白了,没有设置全局配置,只在字段上设置了,这样就出现这个异常。 看了mybatis-plus和mybatis的源代码,mybatis-plus.configuration.default-enum-type-handler是org.apache.ibatis.session.Configuration#setDefaultEnumTypeHandler()里的配置,默认值是EnumTypeHandler

Image

MybatisEnumTypeHandlerEnumTypeHandler的实现方式,是不一样的。可以在这两个类中,debug调试看看差异,或许有惊喜。