Kotlin,Spring Boot,JPA - 获取通用枚举的值 (E.valueOf(stringValue))

Posted

技术标签:

【中文标题】Kotlin,Spring Boot,JPA - 获取通用枚举的值 (E.valueOf(stringValue))【英文标题】:Kotlin, Spring Boot, JPA - take value of a Generic Enum (E.valueOf(stringValue)) 【发布时间】:2021-07-27 16:59:28 【问题描述】:

背景

我正在开发一个 Spring Boot 应用程序,我正在使用 Kotlin、IntelliJ 和 Gradle (Groovy)。我的代码中有一些enum class,我需要保留它们(使用JPA)。我使用了一个简单的全局转换器。

// Sample Enum
enum class Policy 
    PUBLIC,
    INVITE_ONLY


// Sample Converter
@Converter(autoApply = true)
class PolicyConverter : AttributeConverter<Policy, String> 
    override fun convertToDatabaseColumn(attribute: Policy): String 
        return attribute.name
    
    override fun convertToEntityAttribute(dbData: String): Policy 
        return Policy.valueOf(dbData.toUpperCase())
    

问题

因为我有 5-6 个枚举并且我讨厌重复的代码,所以我想到了一个通用转换器,它应该为每个给定的枚举完成工作。我试图编写一些代码,但没有任何效果。这就是我的想法:

abstract class EnumConverter<E: Enum<E>> : AttributeConverter<E, String> 
    override fun convertToDatabaseColumn(attribute: E): String 
        return attribute.name
    

    override fun convertToEntityAttribute(dbData: String): E 
        return E.valueOf(dbData.toUpperCase())
    

这样我只能从一个抽象类扩展每个枚举转换器,如下所示:

@Converter(autoApply = true)
class PolicyConverter : EnumConverter<Policy>() 

这段代码的问题是我有两个错误:

E 是红色的,因为:类型参数 'E' 不能拥有或继承伴随对象,因此它不能位于点的左侧 valueOf 是红色的,因为:未解析的引用(.valueOf 有 150 多种类型)。

根据this 的建议,我尝试使用以下功能:

private inline fun <reified E : Enum<E>> getValue(string: String): E 
    return enumValueOf(string.toUpperCase())

但是当从.convertToEntityAttribute调用时,结果是“不能使用'E'作为具体类型参数。使用类代替。

问题

所以问题很简单:我怎样才能实现一种简单快捷的方法来为我的所有枚举制作一个转换器,所有这些都遵循相同的原则?我只需要一个return E.valueOf(&lt;value&gt;) 函数,但它不存在。

【问题讨论】:

【参考方案1】:

这个问题的一个简单的解决方法是定义一个抽象方法,每个类都将实现它,它会返回正确的类型,给定一个字符串。

// Inside EnumConverter, the Generic Class
abstract class EnumConverter<E: Enum<E>> : AttributeConverter<E, String> 
    abstract fun getValueFromString(string: String) : E

    override fun convertToEntityAttribute(dbData: String): E 
        return getValueFromString(dbData)
    
    [...]


// Inside Policy Enum, implementing
class PolicyConverter : EnumConverter<Policy>() 
    override fun getValueFromString(string: String): Policy 
        return Policy.valueOf(string.toUpperCase())
    

但这是我非常不喜欢的解决方法。

【讨论】:

以上是关于Kotlin,Spring Boot,JPA - 获取通用枚举的值 (E.valueOf(stringValue))的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot - Jpa Distinct 和 Pageable

Spring Boot Kotlin 找不到存储库 Bean

使用 Spring Boot 和 Kotlin 进行 Hibernate 急切加载整个对象图

如何使用 Kotlin 在 Spring JPA 中正确查询实体

Spring Boot(17)——使用Spring Data JPA

spring boot 系列之四:spring boot 整合JPA