【问题标题】:How to get Spring Data to read documents from Mongo that don't have _class attributes如何让 Spring Data 从 Mongo 读取没有 _class 属性的文档
【发布时间】:2014-05-13 19:29:05
【问题描述】:

MongoTemplate 将一个名为“_class”的属性插入到它放入 Mongo 的任何内容中,并且有办法将其关闭。

但是,它似乎不愿意从中读取任何没有 _class 属性的内容。只需从 mongo 文档中删除它似乎就无法访问它。由于读取不是您自己编写的数据是一个明显的用例,我想我一定在这里遗漏了一些东西。

我一直在尝试使用它:

List<SomeClass> list = mongoTemplate.findAll(SomeClass.class, "someCollection");

...SomeClass 使用@Id 和@Document 进行注释,并且 someCollection 中的文档否则会正确映射到对象。我可以通过在代码中创建这些对象之一来验证这一点,使用 insert 将其放入 Mongo,然后看到我可以再次将其读回。

如果 _class 存在,这可以正常工作,但如果不存在,则失败。我不关心多态性或任何可能实际需要此属性的东西。如何让 MongoTemplate 读取它自己没有写入的数据?

【问题讨论】:

    标签: spring mongodb spring-data-mongodb


    【解决方案1】:

    好的,我找到了答案...DavidA的建议是正确的,但缺少关键部分:当您使用null类型映射业务设置MappingMongoConverter dealio时,它不仅停止写入“_class”污染,而且停止试图阅读它。这会导致它回退到您在尝试从 Mongo 检索文档时提供的类型。

    我还没有看到有人真正提到过这一点。 :)

    因此,对于遇到此问题的其他人,这是我使用的 XML 配置(改编自我在 StackOverflow 上的其他地方找到的内容,但我丢失了链接,抱歉):

    <mongo:db-factory id="mongoDbFactory" host="${mongo.host}" port="${mongo.port}" dbname="${mongo.dbname}"/>
    
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
        <constructor-arg name="mongoConverter" ref="mongoConverter" />
        <property name="writeResultChecking" value="EXCEPTION" />
    </bean>
    
    <bean id="mongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
        <constructor-arg name="typeKey"><null/></constructor-arg>
    </bean>
    
    <bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
    
    <bean id="mongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
        <constructor-arg name="mappingContext" ref="mongoMappingContext" />
        <property name="typeMapper" ref="mongoTypeMapper"></property>
    </bean>
    

    然后在Java代码中:

    //build query object
    UnifiedProduct mpp = mongoTemplate.findOne(query, UnifiedProduct.class, "collection-name");
    

    ...这导致了我想要的 UnifiedProduct 类,并且没有烦人的“_class”污染。

    【讨论】:

    • 不错。很高兴知道。我正要发表关于尝试显式转换器的评论,但这是一个更通用的解决方案。感谢您回来并发布完整的答案。
    【解决方案2】:

    Spring 的MappingMongoConverter 使用MongoTypeMapper 来确定从数据库中读取DBObject 时要使用的类型。 DefaultMongoTypeMapper 使用 "_class" 属性按照您的描述工作。

    您应该能够实现自己的MongoTypeMapper 并告诉MappingMongoConberter 使用它。你的版本可以使用其他指标代替"_class"值来判断读取时应该创建什么类型。

    【讨论】:

    • DavidA:感谢您的回复。这听起来像答案是它不能。我对此有点困惑 - 我明确地告诉它我希望它使用什么类(上面 sn-p 中的“SomeClass.class”)所以我不明白为什么它是 spring-data-mongo东西会以这种方式设计,特别是当其他 NoSQL 和/或 JSON 映射实现没有这个限制时。我想我会尝试制作一个始终使用我关心的单一类型的 MongoTypeMapper,看看是否可行。
    猜你喜欢
    • 2020-07-10
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 2016-07-11
    • 2016-05-15
    • 1970-01-01
    相关资源
    最近更新 更多