Spring r2dbc 自定义 Json 转换器不工作

问题描述 投票:0回答:3

我正在尝试使用 spring webflux 和 postgres sql 将 json 插入 json 列。我创建了用于读写的自定义转换器。问题是,每当尝试更新记录时,现有的 json 值就会变为 null。新值也以 json 形式与 null 对象一起插入。 请告诉我哪里做错了

@Configuration
@AllArgsConstructor
@EnableR2dbcRepositories("com.gohunt.hd.hunts.entity")
public class ReactivePostgresConfig extends AbstractR2dbcConfiguration {
private final ObjectMapper objectMapper;

@Bean
@Override
public R2dbcCustomConversions r2dbcCustomConversions() {
    System.out.println("r2dbcCustomConversions ++++++++++++++++++");
    List<Converter<?, ?>> converters = new ArrayList<>();
    converters.add(new JsonToMapConverter(objectMapper));
    converters.add(new MapToJsonConverter(objectMapper));
    return new R2dbcCustomConversions(getStoreConversions(), converters);
}

@Override
public ConnectionFactory connectionFactory() {
    // TODO Auto-generated method stub
    return null; // configured via properties file
}


@Slf4j
@ReadingConverter
@AllArgsConstructor
public class JsonToMapConverter implements Converter<Json, List<SeasonsJsonDto>> {

private final ObjectMapper objectMapper;
@Override
public List<SeasonsJsonDto> convert(Json json) {
    try {
        System.out.println("json +++++++++++++ "+json);
        //return AppJsonUtil.parseMessageAsList(json.toString(), SeasonsJsonDto.class);
        return Arrays.asList(objectMapper.readValue(json.toString(), SeasonsJsonDto[].class));
        
    } catch (Exception e) {
        log.error("Problem while parsing JSON: {}", json, e);
    }
    return new ArrayList<SeasonsJsonDto>();
}

}

@Slf4j
@WritingConverter
@AllArgsConstructor
public class MapToJsonConverter implements Converter<List<SeasonsJsonDto>, Json> {
private final ObjectMapper objectMapper;

@Override
public Json convert(List<SeasonsJsonDto> source) {
    try {
       return Json.of(objectMapper.writeValueAsString(source));
    } catch (JsonProcessingException e) {
        log.error("Error occurred while serializing map to JSON: {}", source, e);
    }
    return Json.of("");
}

}

@Table("aaaa")
@Data
public class HuntsDetail extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column("id")
    private Long id;

    @Column("hunter_id")
    private Long hunterId;

    @Column("hunts_collection_id")
    private String huntCollectionId;

    @Column("folder_id")
    private Long folderId;

    @Column("hunts_coverimgUrl")
    private String huntsCoverImgUrl;

    @Column("seasons_dtl")
    private List<SeasonsJsonDto> seasonsDtl; // json datatype in DB  using above converters to get it as List or json while reading/writing.

}
java spring-webflux spring-data-r2dbc r2dbc r2dbc-postgresql
3个回答
0
投票

我认为这里的答案可能是一个提示。

https://github.com/spring-projects/spring-data-r2dbc/issues/298#issuecomment-586965017

将 List 包装在外部类中怎么样? 我认为这是因为Java的通用类型擦除,所以找不到确切的转换器。


0
投票

我知道这个答案已经晚了,但我觉得我应该添加另一个关于如何做到这一点的观点。我通过使用 json 字段以另一种方式完成此操作,然后转换为映射步骤中我需要的任何对象。

例如,我可能有一个像这样的实体:

import io.r2dbc.postgresql.codec.Json;

@Table("table_name")
@Data
@Builder
public class MyObject {
    @Id
    private Integer id;
    private Json data;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

像 DTO 类

@Data
@Builder
public class MyObjectDTO {
    private Integer id;
    private List<YourObjectType> data;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

然后是一个执行类似操作的映射类:

public MyObjectDTO to(MyObject myObj) {
    try {
        ObjectMapper objectMapper = 
        List<YourObjectType> yourList = objectMapper.readValue(
            myObj.getData().asString(), 
            new TypeReference<List<YourObjectType>>() {});

        return MyObjectDTO.builder()
                .id(myObj.getId())
                .data(yourList)
                .createdAt(myObj.getCreatedAt())
                .updatedAt(myObj.getUpdatedAt())
                .build();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

0
投票

我知道我的回答迟了,但我刚刚遇到了和你一样的问题。 最初的解决方案几乎是正确的,除了

objectMapper.readValue(json.toString(), SeasonsJsonDto[].class)

json.toString()
:会导致类似
JsonByteArrayInput{{"id": 1, "text": "Some text", ...}}
的结果 您应该在 objectMapper.readValue(...) 中使用
json.asString()
。结果字符串将是
{"id": 1, "text": "Some text", ...}

你的转换器应该看起来像这样:

@Slf4j
@ReadingConverter
@AllArgsConstructor
public class JsonToMapConverter implements Converter<Json, List<SeasonsJsonDto>> {

private final ObjectMapper objectMapper;
@Override
public List<SeasonsJsonDto> convert(Json json) {
    try {
        System.out.println("json +++++++++++++ "+json);
        return List.of(objectMapper.readValue(json.asString(), SeasonsJsonDto[].class));
        
    } catch (Exception e) {
        log.error("Problem while parsing JSON: {}", json, e);
    }
    return new ArrayList<>();
}
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.