当前位置: 首页 > 知识库问答 >
问题:

Spring Data R2DBC自定义转换不适用于json数组

彭存
2023-03-14
create table prefecture
(
    id         bigint unsigned auto_increment,
    region_ids json       not null,
    created_at datetime   not null default current_timestamp,
    updated_at datetime   not null default current_timestamp on update current_timestamp,
    constraint prefecture_pk
        primary key (id)
);

--- initial data
INSERT INTO prefecture
VALUES (null, "1", "TEST", json_array(1), now(), now());

然后,我定义了一个实体,该实体对应于该表,如下所示

data class Prefecture(
    @Id
    val id: Int? = null,
    val regionIds: RegionIds,
)

data class RegionIds(
    val list: List<Int>
)

根据这个文档,我发现需要注册一个源类型和目标类型对应的自定义转换器,所以我实现了一个转换器,并像下面这样注册它。

@Configuration
class R2dbcConfiguration {
    @Bean
    fun customConversions(): R2dbcCustomConversions {
        val converters: MutableList<Converter<*, *>?> = ArrayList()
        converters.add(RegionIdsReadConverter())
        return R2dbcCustomConversions(converters)
    }
}

# guessing Row is not appropriate type to source?
@ReadingConverter
class RegionIdsReadConverter : Converter<Row, RegionIds> {
    override fun convert(source: Row): RegionIds {
        val regionIdsString = source.get("region_ids", String::class.java)
        val mapper = ObjectMapper()
        return RegionIds(mapper.readValue(regionIdsString, object : TypeReference<List<Int>>() {}))
    }
}

然后,我试图通过ReactiveCrudRepository获取数据,但我得到了错误:

Could not read property private final jp.foo.bar.models.test.RegionIds jp.foo.bar.models.test.Prefecture.regionIds from column region_ids!
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:177) ~[spring-data-r2dbc-1.2.8.jar:1.2.8]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ Handler jp.foo.bar.controllers.PrefectureController#getAllPrefectures() [DispatcherHandler]
    null

共有1个答案

微生新霁
2023-03-14

最后,我找到了解决这个问题的方法。

首先,我删除了regionidsreadconverter(对应于ditector实体的字段),并添加了一个对应于ditector(实体本身)的转换器。

@ReadingConverter
class PrefectureReadConverter : Converter<Row, Prefecture> {
    override fun convert(source: Row): Prefecture {
        val id = source.get("id", Long::class.java)
        val regionIdsString = source.get("region_ids", String::class.java)
        val mapper = ObjectMapper()
        val regionIds = mapper.readValue(regionIdsString, object : TypeReference<List<Int>>() {})
        return Prefecture(id = id?.toInt(), code = code!!, name = name!!, regionIds = regionIds)
    }
}

另外,我稍微修改了ditecture实体的定义。

data class Prefecture(
    @Id
    val id: Int? = null,
    val regionIds: List<Int>, // eliminate wrapper class RegionIds because it's not necessary anymore
)
@Configuration
class R2dbcConfiguration(
    private val connectionFactory: ConnectionFactory
) : AbstractR2dbcConfiguration() {
    override fun connectionFactory() = connectionFactory
    override fun getCustomConverters() = mutableListOf<Any>(PrefectureReadConverter())
}
org.springframework.data.mapping.MappingException: Could not read property private final boolean xxx.yyy from column zzz!
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Byte] to type [boolean]

因此,如果在注册自定义转换器时不继承Abstractr2DBCConfiguration类,那么r2dbc方言的预定义转换器似乎将不可用。

为了持久化实体,我还必须实现writingconverter:

@WritingConverter
class PrefectureWriteConverter : Converter<Prefecture, OutboundRow> {
    override fun convert(source: Prefecture): OutboundRow {
        val row = OutboundRow()
        with(row) {
            put("id", Parameter.fromOrEmpty(source.id?.toLong(), Long::class.java))
            put("region_ids", Parameter.from(ObjectMapper().writeValueAsString(source.regionIds)))
        }
        return row
    }
}

并登记了。

 类似资料:
  • 我想通过一个自定义的泛型unapply函数压缩我的计算器,该函数计算参数并在成功时返回值。 但是这失败了,错误 有什么方法可以实现这一点吗?我已经研究了类型标签,不适用方法的隐式转换,但我不知道如何将它们集成到这个问题中。如何正确定义Eval?

  • 我有一些自定义角色,例如: 当使用'ROLE_USER'时,“spans”中的文本可以正常显示,但当使用其他角色时,文本无法显示。然后我在自定义角色中添加'ROLE_'前缀,它又变得正常了。 我尝试删除“ROLE\uu0”前缀约束,如下所示: 它也不起作用。知道如何删除强制的“ROLE\uuux”前缀吗?

  • 我使用spring boot和spring boot starter hateoas开发了一个rest服务。我在定制ObjectMapper时遇到了一个问题。代码如下: 一个pplication.java 依赖关系: 账单java: BillController.java: 我得到的输出是: 但是我需要“账单”代替“billList”。这是因为ObjectMapper没有被定制。我是否错过了任何配

  • 我有一个Flume组件在监听Syslog流。我做了一个自定义的拦截器来修改调用,但它不起作用。我做错了什么?谢谢你,Andrea 拦截器是一个编译良好的JAR文件,位于@FLUME_HOME/bin目录中 系统将事件记录在文件中而不修改它们,这是相关的DEBUG日志:

  • 我对大摇大摆的文档很陌生。我们有一个现有的项目正在为RESTFul Web服务开发进度语言。不同的基于资源的URL以Application/JSON格式使用和生成。下面给出了一个资源url的输入和输出json格式: 如何将上述请求和响应json格式转换为swagger 2.0 json格式? 谢了!

  • 我试图用以下格式转换一个JSON: 我已经计算了JSON,现在我需要使用evaluatejsonpath输出中的属性来获得以下格式: 它们是内置的处理器来完成此转换吗,还是需要在executionscript处理器中开发一个Python脚本?

  • 问题内容: 我几乎是新来的。我正在尝试创建一个简单的编辑和创建蒙版。这是代码: Company类如下所示: 现在我的问题是,当我单击时,为什么不触发该事件。 在这一部分: 问题答案: 原因很简单,当您点击 它不是在组件上设置的事件,而是传递给组件并可以像在Company组件中一样访问的prop , 您需要做的是指定事件,并在Company组件中指定 作为prop传递给组件的函数可以通过任何名称传递

  • 代码如下: 这是适配器,我在这里为列表做了自己的设计(< code>R.layout.zalistu),它在仿真器中工作,但在设备上它给我一个错误(应用程序意外停止),如果我使用< code>simple_list_item_1,那么它在仿真器和我的设备上都可以正常工作。 这里是R:layout.zalistu: 日志猫: 我设备上的Android版本是2.3.7,模拟器上的版本是4.0.4(AP