我正在尝试使用 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.
}
我认为这里的答案可能是一个提示。
https://github.com/spring-projects/spring-data-r2dbc/issues/298#issuecomment-586965017
将 List 包装在外部类中怎么样? 我认为这是因为Java的通用类型擦除,所以找不到确切的转换器。
我知道这个答案已经晚了,但我觉得我应该添加另一个关于如何做到这一点的观点。我通过使用 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);
}
}
我知道我的回答迟了,但我刚刚遇到了和你一样的问题。 最初的解决方案几乎是正确的,除了
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<>();
}