java - 使用 Spring Data 将 io.vavr.collection.Map 存储到 MongoDB
问题描述
我在使用 Spring Data 将序列化和反序列化 vavr 映射到 MongoDB 时遇到问题。
编码
public class Location {
public final Map<String, String> region;
public Location() {
this.region = HashMap.of("City", "Warsaw", "Country", "Poland");
}
}
public interface LocationRepository extends CrudRepository<Location, String> {
}
@SpringBootApplication
public class VavrMapMongoApplication {
public static void main(String[] args) {
SpringApplication.run(VavrMapMongoApplication.class, args);
}
@Bean
public CommandLineRunner importData(LocationRepository repository) {
return (String... args) -> {
final Location location = new Location();
repository.save(location);
};
}
}
给了我一个例外:
Caused by: java.lang.ClassCastException: class io.vavr.collection.HashMap cannot be cast to class java.util.Map (io.vavr.collection.HashMap is in unnamed module of loader 'app'; java.util.Map is in module java.base of loader 'bootstrap')
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:582) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeProperties(MappingMongoConverter.java:550) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:526) ~[spring-data-mongodb-2.1.6.RELEASE.jar:2.1.6.RELEASE]
我用@WritingConverter
and解决了这个问题@ReadingConverter
:
@Configuration
public class VavrCustomConverter {
@Bean
public MongoCustomConversions customConversions() {
return new MongoCustomConversions(asList(new VavrMapToMapConverter(), new MapToVavrMapConverter()));
}
@WritingConverter
private static class VavrMapToMapConverter implements Converter<Map, java.util.Map> {
@Override
public java.util.Map convert(Map map) {
return map.toJavaMap();
}
}
@ReadingConverter
private static class MapToVavrMapConverter implements Converter<java.util.Map, Map> {
@Override
public Map convert(java.util.Map map) {
return HashMap.ofAll(map);
}
}
}
但它仅在HashMap
包含 java 原始类型时才有效。当我将代码更改为:
public class Region {
public final String country;
public final String city;
public Region(String country, String city) {
this.country = country;
this.city = city;
}
}
public class Location {
public final Map<String, Region> region;
public Location(Map<String, Region> region) {
this.region = region;
}
}
@Bean
public CommandLineRunner importData(LocationRepository repository) {
return (String... args) -> {
final Region region = new Region("Poland", "Warsaw");
final HashMap<String, Region> pl = HashMap.of("PL", region);
final Location location = new Location(pl);
repository.save(location);
}
我有例外:
Caused by: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class test.vavrmapmongo.Region.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46) ~[bson-3.8.2.jar:na]
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63) ~[bson-3.8.2.jar:na]
为什么?java.util.Map
用 POJO 很好地序列化到 MongoDB。我正在寻找使用 vavr Map 的通用方法(不是仅用于Region
类的文档转换器)。
解决方案
推荐阅读
- html - 创建一个交易卡简单的网站页面
- javascript - 根据另一个选择更改选择选项
- python - 不在 Tkinter 中显示图像
- python - 如何使用精度和召回等指标评估 Pytorch 模型?
- python - 如何计算 tsv 文件中以特定字符串结尾的行数?
- spring-integration - 使用 Spring Integration 使用流数据
- java - 在执行下面的代码时,我得到 NullPointerException
- c++ - 将 std::allocate_shared 与多态资源分配器一起使用
- r - 如何使用 dplyr 仅加入某些行?
- d3.js - Vega-Lite API 中带有多系列折线图的工具提示