Spring Data MongoDB忽略了_class信息

时间:2014-01-08 15:39:38

标签: class spring-data spring-data-mongodb

使用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启动时注册吗?),但是我无法找到错误的配置。有没有人有类似的问题或有一些建议?

2 个答案:

答案 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实例中提交一张票。