You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用@Enumerated(EnumType.STRING)存储枚举后,无法从数据库取回枚举的问题

问题原因

@Enumerated(EnumType.STRING) 默认是将枚举常量名称(比如你的枚举里的A、B、C)与数据库字符串做映射,但你的枚举每个常量对应了自定义字符串(apple、banana、cherry),存入数据库的是这些自定义值,读取时JPA会尝试用数据库中的字符串(比如banana)去匹配枚举的常量名称,自然找不到对应枚举,所以抛出No enum constant异常。

解决方案

要实现自定义枚举值与数据库字符串的双向转换,需要自定义JPA属性转换器,步骤如下:

1. 完善枚举类

添加自定义字段、构造方法,以及根据字符串反向查找枚举的静态方法:

public enum EducationType {
    A("apple"),
    B("banana"),
    C("cherry");

    private final String value;

    EducationType(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    // 根据数据库字符串反向匹配枚举
    public static EducationType fromValue(String value) {
        for (EducationType type : EducationType.values()) {
            if (type.value.equals(value)) {
                return type;
            }
        }
        throw new IllegalArgumentException("未找到匹配的枚举值: " + value);
    }
}

2. 实现JPA属性转换器

创建转换器类,处理枚举与数据库字符串的双向转换:

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;

@Converter(autoApply = true) // autoApply=true 会自动应用到所有EducationType类型的字段
public class EducationTypeConverter implements AttributeConverter<EducationType, String> {

    @Override
    public String convertToDatabaseColumn(EducationType attribute) {
        // 枚举转数据库字符串
        return attribute == null ? null : attribute.getValue();
    }

    @Override
    public EducationType convertToEntityAttribute(String dbData) {
        // 数据库字符串转枚举
        return dbData == null ? null : EducationType.fromValue(dbData);
    }
}

3. 实体类字段配置

实体类中的枚举字段无需再使用@Enumerated注解,转换器会自动处理转换:

// 实体类中的字段定义
private EducationType educationType;

如果不想全局自动应用转换器,也可以在字段上单独指定:

import jakarta.persistence.Convert;

@Convert(converter = EducationTypeConverter.class)
private EducationType educationType;

内容的提问来源于stack exchange,提问作者zhrgci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:35:23