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

如何使用Spring Data @WritingConverter和@ReadingConverter并作用于指定字段?

问题

我的Kotlin实体中有一个String类型字段,需要与数据库的BIGINT列适配,想用Spring Data的@WritingConverter和@ReadingConverter解决,但找不到合适的示例或文档。

不使用转换器时,保存/查询操作会报错:
PostgresqlBadGrammarException: operator does not exist: bigint = character varying

我已经配置了自定义转换器:

@Configuration
@EnableR2dbcRepositories
class R2dbcConfiguration {
    @Bean
    fun r2dbcCustomConversions(
        stringToBigIntConverter: StringToBigIntConverter,
        bigIntToStringConverter: BigIntToStringConverter
    ): R2dbcCustomConversions {
        return R2dbcCustomConversions(listOf(stringToBigIntConverter, bigIntToStringConverter))
    }
}

自定义转换器代码:

@Component
@WritingConverter
class BigIntToStringConverter: Converter<Long, String> {
    override fun convert(source: Long): String {
        return source.toString()
    }
}

@Component
@WritingConverter
class StringToBigIntConverter: Converter<String, Long> {
    override fun convert(source: String): Long {
        return source.toLong()
    }
}

但现在转换器会对所有String字段和BIGINT列进行互转,请问如何让转换器仅作用于特定实体的特定字段?


解决方案

要让转换器仅作用于特定字段,不能使用全局的Converter(会匹配所有对应类型的字段/列),推荐通过自定义标记类型+针对性转换器的方式实现,步骤如下:

  1. 定义一个仅用于标记的自定义类型,用来区分需要转换的String字段
// 自定义类型,仅作为转换标记,实际存储值为String
data class BigIntAsString(val value: String)
  1. 修改实体类中目标字段的类型为自定义类型,同时通过@Column指定数据库列类型
@Table("your_table_name")
data class TargetEntity(
    // 其他字段...
    @Column(name = "target_bigint_column", columnDefinition = "BIGINT")
    val specificField: BigIntAsString
)
  1. 调整转换器,让其仅处理自定义类型与Long的互转,这样只会匹配实体中该自定义类型的字段
@Component
@ReadingConverter // 数据库读取:Long → 实体的BigIntAsString
class BigIntToBigIntAsStringConverter : Converter<Long, BigIntAsString> {
    override fun convert(source: Long): BigIntAsString {
        return BigIntAsString(source.toString())
    }
}

@Component
@WritingConverter // 写入数据库:实体的BigIntAsString → Long
class BigIntAsStringToBigIntConverter : Converter<BigIntAsString, Long> {
    override fun convert(source: BigIntAsString): Long {
        return source.value.toLong()
    }
}
  1. 保持原有的R2dbcCustomConversions配置,替换为新的转换器即可
@Configuration
@EnableR2dbcRepositories
class R2dbcConfiguration {
    @Bean
    fun r2dbcCustomConversions(
        bigIntToConverter: BigIntToBigIntAsStringConverter,
        bigIntFromStringConverter: BigIntAsStringToBigIntConverter
    ): R2dbcCustomConversions {
        return R2dbcCustomConversions(listOf(bigIntToConverter, bigIntFromStringConverter))
    }
}

额外说明

  • 原转换器的注解存在错误:StringToBigIntConverter应该用@ReadingConverter(从数据库读取时转换),BigIntToStringConverter应该用@WritingConverter(写入数据库时转换),使用自定义类型的方式可以避免这种注解混淆。
  • 如果不想新增自定义类型,也可以尝试在目标字段上使用@Convert(converter = XXXConverter::class)注解,但Spring Data R2DBC对该注解的支持需确保版本兼容性,自定义类型的方式更稳定可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:10:00