JPA端点查询需显式类型转换:枚举匹配报错解决方案咨询
解决方案
1. 优先修正枚举值与数据库的一致性问题
注意到枚举类中是CANCELED,但数据库迁移脚本中定义的是CANCELLED(多了一个L),这会直接导致转换失败,必须先修正:
- 要么修改枚举类:
enum class ExchangeRequestStatus(val value: String) { PENDING("PENDING"), ACCEPTED("ACCEPTED"), REJECTED("REJECTED"), CANCELLED("CANCELLED") }
- 要么修改数据库迁移脚本:
CREATE TYPE EXCHANGE_REQUEST_STATUS AS ENUM ('PENDING', 'ACCEPTED', 'REJECTED', 'CANCELED');
2. 在JPQL查询中显式转换参数类型
修改Repository的查询语句,将参数转换为数据库枚举类型:
@Query("SELECT er FROM ExchangeRequest er WHERE er.status = CAST(:status AS EXCHANGE_REQUEST_STATUS)") fun findByStatus(status: ExchangeRequestStatus): Optional<List<ExchangeRequest>>
如果JPQL的CAST不生效,可以改用原生SQL查询:
@Query(value = "SELECT * FROM exchange_request er WHERE er.status = CAST(?1 AS exchange_request_status)", nativeQuery = true) fun findByStatus(status: ExchangeRequestStatus): Optional<List<ExchangeRequest>>
3. 自定义JPA枚举转换器
创建转换器类让JPA自动处理枚举与数据库类型的映射,无需修改查询语句:
import javax.persistence.AttributeConverter import javax.persistence.Converter @Converter(autoApply = true) class ExchangeRequestStatusConverter : AttributeConverter<ExchangeRequestStatus, String> { override fun convertToDatabaseColumn(attribute: ExchangeRequestStatus?): String? { return attribute?.value } override fun convertToEntityAttribute(dbData: String?): ExchangeRequestStatus? { return dbData?.let { value -> ExchangeRequestStatus.values().firstOrNull { it.value == value } } } }
然后在实体类的枚举字段上添加注解:
@Column(name = "status", nullable = false) @Convert(converter = ExchangeRequestStatusConverter::class) private var status: ExchangeRequestStatus,
内容的提问来源于stack exchange,提问作者vale383
相关产品推荐
相关产品推荐

