使用spring-data-mongodb 1.3.3.RELEASE和Java 1.6时遇到了一些麻烦。
我的设置有点复杂,因为我必须处理遗留数据,所以我有一个自定义TypeMapper
(扩展DefaultMongoTypeMapper
)和两个不同的读/写转换器组合。另外,我使用@TypeAlias
来设置数据库中的_class
信息。
有问题的模型由几个嵌套列表组成,有些列表类似
List<DocumentValue>
MyObject可能包含对象列表
List<Object>
可能包含另一个DocumentValue
对象。
此设置似乎有效,单元测试运行没有任何问题,对象映射在调试器中看起来相当不错。我的应用程序是一个Web应用程序,我可以将DocumentValue
写入集合,_class
信息存在。
只要我不关闭服务器(在我的情况下是tomcat),对象映射就可以了。但是,当我重新启动服务器(启动新的JVM)时,DocumentValue
对象未正确映射但被视为java.util.Map
。 _class
信息似乎被忽略了。我想我的映射上下文可能有问题(我的模型实体应该在Spring Context启动时注册吗?),但是我无法找到错误的配置。有没有人有类似的问题或有一些建议?
答案 0 :(得分:1)
感谢您的回复。我想我找到了_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的所有TypeInformation,我将@Document添加到每个持久化的模型bean中 - 以防万一;)
也许这对有类似问题的其他人有帮助。
此致 克里斯托弗
答案 1 :(得分:0)
我怀疑由于TypeMapper
使用和转换器的异常组合而导致问题发生。 如果注册了特定类型的手动实现的Converter
实例,那么Converter
负责创建一个可由MongoDB保持可读和可读的对象。这意味着您的转换器实例需要自己编写类型信息。
如果你无法使它工作并且可以编译一个小的示例项目来重现问题(最好是要执行的测试用例),请随意在我们的JIRA实例中提交一张票。