MongoDB中对象反序列化的一个小问题

本文介绍了在使用MongoDB存取对象数据时遇到的问题:对象包含抽象类或接口类型的字段,在读取时无法完成对象重建并抛出错误。通过在初始化时调用ObjectMapper的enableDefaultTyping方法,可以实现抽象类声明的成员变量的重新构建,解决了此问题。

今天在mongoDB存取对象数据的时候,碰到一个小问题:对象的某一个字段类型是抽象类或者接口,在存入的时候没有问题,但是在读取的时候,由于没有具体类的信息,无法完成对象的重新构建,就会报错:

Can not construct instance of com.bp.samples.json.generics.xxx, 
problem: abstract types either need to be mapped to concrete types, have custom 
deserializer, or be instantiated with additional type information
at [Source:xxxxx]
搜索了一下,有一种方法是给父类加注解,标明继承该父类的所有具体类的名字,网址:
http://blog.youkuaiyun.com/java_huashan/article/details/46428971

但是这种方法由一个局限性,如果我的具体子类是可拓展的,那么每次都要修改源代码上面的注解。如果是父类是在框架里,在jar包中,可能就不妥了。

经人指点,找到另一种比较好的方法,就是在http://wiki.fasterxml.com/JacksonPolymorphicDeserialization中提到的enableDefaultTyping一部分,在mongoDB客户端初始化的时候objectMapper对象调用这个方法就可以做到重新构建抽象类声明的成员变量。

像这样:mapper = new ObjectMapper();
mapper.enableDefaultTyping();


### 解决 Spring Boot 与 MongoDB 序列化问题 当处理 Spring Boot 和 MongoDB 的序列化配置时,有几个关键点需要注意。默认情况下,Spring Data MongoDB 使用 Jackson 来执行对象和 BSON 文档之间的转换。 #### 配置自定义序列化器和反序列化器 为了更好地控制如何将 Java 对象映射到 MongoDB 中的文档以及反之亦然的过程,可以通过创建并注册 `CustomConversions` 实现来指定自己的序列化逻辑: ```java @Configuration public class MongoConfig { @Bean public CustomConversions customConversions() { List<Converter<?, ?>> converters = new ArrayList<>(); converters.add(new MyTypeToDBObject()); converters.add(new DBObjectToMyType()); return new CustomConversions(converters); } } ``` 这里假设有一个名为 `MyType` 的类需要特别对待,在上述例子中实现了两个转换器:一个是用于保存数据前将其转成数据库友好的形式;另一个是在读取记录之后恢复原始状态[^1]。 #### 处理复杂的数据结构 对于更复杂的场景,比如嵌套的对象或者特定类型的字段(如日期),可能还需要调整应用中的实体模型注解方式。例如,使用 `@JsonSerialize` 或者 `@JsonDeserialize` 注解来自定义 JSON 表达式的生成过程[^2]。 另外,如果遇到时间戳存储的问题,则应该考虑设置全局的时间格式化策略: ```yaml spring: data: mongodb: auto-index-creation: true jackson: date-format: yyyy-MM-dd'T'HH:mm:ss.SSSZ ``` 这段 YAML 文件片段展示了怎样通过应用程序属性文件改变默认行为,从而确保所有地方都遵循统一的标准[^3]。 #### 常见错误及其解决方案 有时开发者会碰到一些常见的异常情况,像找不到合适的 getter/setter 方法、循环引用等问题。针对这些问题,建议仔细检查 POJO 类的设计是否合理,并且确认已经正确设置了必要的访问级别修饰符(public/private/protected)。此外,也可以尝试启用调试日志以便于定位具体原因所在之处。 ```properties logging.level.org.springframework.data=DEBUG ``` 以上措施有助于排查潜在冲突并找到有效的修正途径。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值