我在使用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。这意味着您的转换器实例需要自己编写类型信息。

如果你不能让它工作,并且可以编译一个小样本项目来重现这个问题(最好是一个测试用例来执行),请随时在我们的 吉拉 实例。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top