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

Grails2升级到Grails4后出现No enum constant枚举报错如何解决

问题原因

Grails 4底层依赖的Hibernate 5.x对枚举的默认持久化策略和Grails 2不同:

  • Grails 2会默认识别枚举中的自定义id字段,将id值持久化到数据库
  • Grails 4默认使用EnumType.STRING策略,直接存储枚举的字面量名称(如NO_RESULTS、RACE_RESULTS)

你数据库中现存的resultsStatus字段值是之前版本写入的1/2/3整数值,GORM读取时会直接把整数值作为枚举名去匹配,找不到对应实例就会抛出No enum constant com.company.compositeEvent.ResultsStatus.2错误。

解决方案(无需修改现有数据库数据,兼容性最优)

第一步:修改ResultsStatus枚举,补充按id查找的静态方法

enum ResultsStatus {

    NO_RESULTS(1),
    RACE_RESULTS(2),
    EXTERNAL_RESULTS(3)

    int id

    private ResultsStatus(int id){
        this.id = id
    }

    // 新增:根据存储的id值获取对应枚举实例
    static ResultsStatus getById(int id) {
        return values().find { it.id == id }
    }
}

第二步:编写枚举属性转换器,实现数据库值和枚举实例的互转

新建ResultsStatusConverter类:

import javax.persistence.AttributeConverter
import javax.persistence.Converter

@Converter(autoApply = true)
class ResultsStatusConverter implements AttributeConverter<ResultsStatus, Integer> {

    // 枚举转数据库存储值
    @Override
    Integer convertToDatabaseColumn(ResultsStatus status) {
        return status?.id
    }

    // 数据库存储值转枚举实例
    @Override
    ResultsStatus convertToEntityAttribute(Integer id) {
        return id ? ResultsStatus.getById(id) : null
    }
}

第三步:给CompositeEvent中的resultsStatus属性绑定转换器

找到CompositeEvent类的resultsStatus属性定义,加@Convert注解:

import javax.persistence.Convert

// ...其他属性
@Convert(converter = ResultsStatusConverter)
ResultsStatus resultsStatus
// ...其他属性

配置完成后重启应用即可正常读写枚举值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:57:02