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
相关产品推荐
相关产品推荐

