【问题标题】:Spring Boot & MongoDB how to remove the '_class' column?Spring Boot 和 MongoDB 如何删除 '_class' 列?
【发布时间】:2014-06-24 10:34:51
【问题描述】:

在将数据插入MongoDB时,Spring Data添加了一个自定义的“_class”列,在使用Spring Boot & MongoDB时,有没有办法消除“class”列?

或者我需要创建一个自定义类型映射器吗?

任何提示或建议?

【问题讨论】:

标签: spring-data spring-boot


【解决方案1】:

上面的正确答案似乎是使用了一些已弃用的依赖项。例如,如果您检查代码,它会提到在最新的 Spring 版本中已弃用的 MongoDbFactory。如果你碰巧在 2020 年将 MongoDB 与 Spring-Data 一起使用,那么这个解决方案似乎更老了。如需即时结果,请检查此 sn-p 代码。工作 100%。 只需创建一个新的 AppConfig.java 文件并粘贴此代码块。您会看到“_class”属性从 MongoDB 文档中消失。

package com.reddit.redditmain.Configuration;

import org.apache.naming.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;  
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

@Configuration
public class AppConfig {

@Autowired
MongoDatabaseFactory mongoDbFactory;
@Autowired
MongoMappingContext mongoMappingContext;

@Bean
public MappingMongoConverter mappingMongoConverter() {

    DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
    MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
    converter.setTypeMapper(new DefaultMongoTypeMapper(null));

    return converter;
    }

}

【讨论】:

    【解决方案2】:

    类似于 RZet,但避免继承:

    @Configuration
    public class MongoConfiguration {
    
        @Autowired
        private MappingMongoConverter mappingMongoConverter;
    
        // remove _class
        @PostConstruct
        public void setUpMongoEscapeCharacterConversion() {
            mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      一种简单的方法(+ 表示 ReactiveMongoTemplate):

        @Configuration
        public class MongoDBConfig {
      
          @Autowired
          private MongoClient mongoClient;
      
          @Value("${spring.data.mongodb.database}")
          private String dbName;
      
          @Bean
          public ReactiveMongoTemplate reactiveMongoTemplate() {
            ReactiveMongoTemplate template = new ReactiveMongoTemplate(mongoClient, dbName);
            MappingMongoConverter converter = (MappingMongoConverter) template.getConverter();
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
            converter.afterPropertiesSet();
            return template;
          }
        }
      

      【讨论】:

        【解决方案4】:

        这里有一个稍微简单的方法:

        @Configuration
        public class MongoDBConfig implements InitializingBean {
        
            @Autowired
            @Lazy
            private MappingMongoConverter mappingMongoConverter;
        
            @Override
            public void afterPropertiesSet() throws Exception {
                mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
            }
        }
        

        【讨论】:

          【解决方案5】:

          对该问题的最新答案,使用嵌入式 mongo db 进行测试用例: 我引用http://mwakram.blogspot.fr/2017/01/remove-class-from-mongo-documents.html

          Spring Data MongoDB 在 mongo 文档中添加 _class 来处理 java继承的多态行为。如果要删除 _class 只需在您的代码中删除以下 Config 类即可。

          package com.waseem.config;
          
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.data.mongodb.MongoDbFactory;
          import org.springframework.data.mongodb.core.convert.DbRefResolver;
          import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
          import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
          import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
          import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
          
          @Configuration
          public class MongoConfig {
          
           @Autowired MongoDbFactory mongoDbFactory;
           @Autowired MongoMappingContext mongoMappingContext;
          
           @Bean
           public MappingMongoConverter mappingMongoConverter() {
          
            DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
            MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
          
            return converter;
           }
          }
          

          【讨论】:

            【解决方案6】:

            添加一个转换器来移除类。

            MappingMongoConverter converter =
                    new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());
                converter.setTypeMapper(new DefaultMongoTypeMapper(null));
            
            MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
            
                return mongoTemplate;
            

            `

            【讨论】:

              【解决方案7】:

              戴夫的回答是正确的。但是,我们通常建议不要这样做(这就是为什么它首先默认启用的原因),因为您有效地丢弃了持久类型层次结构甚至是设置为例如的简单属性。 Object。假设以下类型:

              @Document
              class MyDocument {
              
                private Object object;
              }
              

              如果您现在将 object 设置为一个值,它会很高兴地被持久化,但您无法将该值读回它的原始类型。

              【讨论】:

              • 感谢@Oliver 提供的额外细节,起初我认为 _class 没用,但现在有了 Spring Data 提供的“魔法”,它变得更有意义了。
              • @Oliver:虽然我看到您的观点总体上很重要,但有一个例外,我认为这是一个主要用例。如果一个人有一个映射到集合的 MongoRepository (并且希望说一个人没有愚蠢到通过将其他任何东西映射到该集合来射击自己的脚),并且 T 不是抽象的,并且没有使用继承类@Entity,那么我绝对应该能够删除 _class 而不会影响该回购正确水合 T 的能力。你同意吗,还是我忽略了其他障碍?
              【解决方案8】:

              我认为您需要创建一个 MongoTemplate 类型的 @Bean 并明确设置类型转换器。详细信息(非Boot但只提取模板配置):http://www.mkyong.com/mongodb/spring-data-mongodb-remove-_class-column/

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-10-12
                • 2022-01-21
                • 2020-03-20
                • 2020-10-17
                • 1970-01-01
                • 2019-09-02
                • 2021-06-17
                相关资源
                最近更新 更多