Spring Data MongoDB忽略_class信息
-
20-12-2019 - |
题
我在使用spring-data-mongodb1.3.3时遇到了一些麻烦。发布和Java1.6。
我的设置有点复杂,因为我必须处理遗留数据,所以我有一个自定义 TypeMapper
(延伸 DefaultMongoTypeMapper
)和两种不同的读/写转换器组合。另外我用 @TypeAlias
用于设置 _class
数据库中的信息。
有问题的模型由几个嵌套列表组成,有些类型如下
List<DocumentValue>
MyObject可能包含对象列表
List<Object>
其中可能包含另一个 DocumentValue
对象。
这个设置似乎有效,单元测试运行没有任何问题,对象映射在调试器中看起来相当不错。我的应用程序是一个web应用程序,我能够编写 DocumentValue
它变成了一个集合, _class
信息存在。
只要我不关闭服务器(在我的情况下是tomcat),对象映射就可以工作。但是当我重新启动服务器(启动一个新的JVM), DocumentValue
对象未正确映射,但被视为 java.util.Map
.该 _class
信息似乎被忽略了。我想我的映射上下文可能有问题(我的模型实体应该在Spring上下文启动时注册吗?),但我无法找到错误配置。有没有人有一些类似的问题或有一些建议?
解决方案
谢谢你的回复。我想我找到了_class被忽略的原因。你是对的,我使用TypeMapper的一个不寻常的组合。
让我告诉你我的CustomTypeMapper:
public class CustomTypeMapper extends DefaultMongoTypeMapper {
public CustomTypeMapper (MongoMappingContext mappingContext) {
super(DEFAULT_TYPE_KEY,
Arrays.asList(new MappingContextTypeInformationMapper(
mappingContext)));
}
@Override
public <T> TypeInformation<? extends T> readType(DBObject source,
TypeInformation<T> basicType) {
// do some custom recognition
// or just to the common type mapping
return super.readType(source, basicType);
}
}
除了通用类型识别之外,一个特殊的东西是构造函数,其中MappingContextTypeInformationMapper用于使用@TypeAlias注释。
这里的关键是需要的MongoMappongContext。在非功能的情况下,我初始化了CustomTypeMapper,如下所示
<bean id="customTypeMapper" class="de.flexguse.repository.CustomTypeMapper">
<constructor-arg name="mappingContext">
<bean class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
</constructor-arg>
</bean>
这工作,但是错误的,因为MongoMappingContext的新实例不包含通过设置base-package属性提供的任何TypeInformation
<mongo:mapping-converter id="customMappingConverter" db-factory-ref="mongoDbFactory"
type-mapper-ref="customTypeMapper" base-package="de.flexguse.model" >
<mongo:custom-converters>
... some custom converters ...
</mongo:custom-converters>
</mongo:mapping-converter>
不幸的是,我无法弄清楚MongoMappingContext是在哪里创建的,以便能够将其用作构造函数参数,因此我发明了一个简单的bean MongoMappingContextProvider,它使用@Autowire获取MongoMappingContext
public class MongoMappingContextProvider {
@Autowired
private MongoMappingContext mappingContext;
/**
* @return the mappingContext
*/
public MongoMappingContext getMappingContext() {
return mappingContext;
}
}
CustomTypeMapper的Spring配置现在如下所示
<bean id="mongoMappingContextProvider" class="de.flexguse.repository.MongoMappingContextProvider" />
<bean id="customTypeMapper" class="de.flexguse.repository.CustomTypeMapper">
<constructor-arg name="mappingContext" value="#{mongoMappingContextProvider.mappingContext}" />
</bean>
这个解决方案适用于我。
顺便说一句,为了确保我使用的所有模型bean的所有TypeInformations,我将@Document添加到每个持久化的模型bean中-以防万一;)
也许这对其他有类似问题的人有帮助。
问候, 克里斯托夫
其他提示
我怀疑这个问题是由于不寻常的组合而发生的。 TypeMapper
用法和转换器。 如果 一个手动实现的 Converter
一个特定类型的实例被注册, Converter
负责创建一个对象持久性和可读的MongoDB。这意味着您的转换器实例需要自己编写类型信息。
如果你不能让它工作,并且可以编译一个小样本项目来重现这个问题(最好是一个测试用例来执行),请随时在我们的 吉拉 实例。