복붙노트

[MONGODB] 봄의 데이터 MongoDB를 : MappingMongoConverter의 제거 _class

MONGODB

봄의 데이터 MongoDB를 : MappingMongoConverter의 제거 _class

기본 MappingMongoConverter은 데이터베이스에있는 각 개체에 사용자 정의 형 키 ( "_class")를 추가합니다. 그래서, 나는 사람을 만드는 경우 :

package my.dto;
public class Person {
    String name;
    public Person(String name) {
        this.name = name; 
    }
}

그리고 DB에 저장합니다 :

MongoOperations ops = new MongoTemplate(new Mongo(), "users");
ops.insert(new Person("Joe"));

몽고의 결과 개체가 될 것입니다 :

{ "_id" : ObjectId("4e2ca049744e664eba9d1e11"), "_class" : "my.dto.Person", "name" : "Joe" }

질문 :

해결법

  1. ==============================

    1.그래서 여기 이야기 : 우리가 실제로 어떤 클래스의 인스턴스를 생성하기위한 힌트의 일종으로 기본적으로 유형을 추가 할 수 있습니다. 당신은 MongoTemplate 어쨌든 두 가지 옵션이 있습니다를 통해로 문서를 읽을 수있는 형태로 파이프를 가지고 :

    그래서 여기 이야기 : 우리가 실제로 어떤 클래스의 인스턴스를 생성하기위한 힌트의 일종으로 기본적으로 유형을 추가 할 수 있습니다. 당신은 MongoTemplate 어쨌든 두 가지 옵션이 있습니다를 통해로 문서를 읽을 수있는 형태로 파이프를 가지고 :

    당신은 실제의 형태로 형식 정보를 설정하는 플러그 타입 매핑 전략의 어떤 종류를 커버이 티켓을 시청에 관심이있을 수 있습니다. 당신은 몇 글자의 해시에 긴 클래스 이름을 절감 할 수 있습니다 이것은 목적을 절약 단순히 공간을 제공 할 수 있습니다. 그것은 또한 당신이 다른 데이터 저장소 클라이언트와 바인드 자바 유형들에 의해 생산 완전히 임의의 타입의 키를 찾을 수 있습니다 더 복잡한 마이그레이션 시나리오를 허용합니다.

  2. ==============================

    2.여기 내 주석, 그리고 그것을 작동합니다.

    여기 내 주석, 그리고 그것을 작동합니다.

    @Configuration
    public class AppMongoConfig {
    
        public @Bean
        MongoDbFactory mongoDbFactory() throws Exception {
            return new SimpleMongoDbFactory(new Mongo(), "databasename");
        }
    
        public @Bean
        MongoTemplate mongoTemplate() throws Exception {
    
            //remove _class
            MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
    
            MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
    
            return mongoTemplate;
    
        }
    
    }
    
  3. ==============================

    3.당신은 기본적으로 비활성화 _class 속성을 원하지만 지정된 클래스 polymorfism을 유지하는 경우, 당신은 명시 적으로 configuing으로 _class (선택 사항) 필드의 유형을 정의 할 수 있습니다 :

    당신은 기본적으로 비활성화 _class 속성을 원하지만 지정된 클래스 polymorfism을 유지하는 경우, 당신은 명시 적으로 configuing으로 _class (선택 사항) 필드의 유형을 정의 할 수 있습니다 :

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        Map<Class<?>, String> typeMapperMap = new HashMap<>();
        typeMapperMap.put(com.acme.domain.SomeDocument.class, "role");
    
        TypeInformationMapper typeMapper1 = new ConfigurableTypeInformationMapper(typeMapperMap);
    
        MongoTypeMapper typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(typeMapper1));
        MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());
        converter.setTypeMapper(typeMapper);
    
        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
        return mongoTemplate;
    }
    

    이 _class 필드를 보존 (또는 무엇이든 당신은 생성자에서 이름을 지정할) 만 지정된 엔티티.

    또한 주석을 기준으로 예를 들어 자신의 TypeInformationMapper을 작성할 수 있습니다. 당신이 @DocumentType ( "를 AliasName")하여 문서에 주석을 경우에 당신은 클래스의 별칭을 유지하여 다형성을 유지합니다.

    내 블로그에 간단히 설명했지만, 여기에 빠른 코드의 일부 조각입니다 : https://gist.github.com/athlan/6497c74cc515131e1336

  4. ==============================

    4.

    <mongo:mongo host="hostname" port="27017">
    <mongo:options
    ...options...
    </mongo:mongo>
    <mongo:db-factory dbname="databasename" username="user" password="pass"                     mongo-ref="mongo"/>
    <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>
    <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>
    
  5. ==============================

    5., Mkyong의 대답은 여전히 ​​작동하는 동안, 나는 몇 비트가 사용되지 않습니다으로 솔루션의 나의 버전을 추가 할 및 정리의 가장자리에있을 수있다.

    , Mkyong의 대답은 여전히 ​​작동하는 동안, 나는 몇 비트가 사용되지 않습니다으로 솔루션의 나의 버전을 추가 할 및 정리의 가장자리에있을 수있다.

    예를 들어 : MappingMongoConverter (mongoDbFactory (), 새로운 MongoMappingContext는 ()) 새로운 MappingMongoConverter 찬성되지 않습니다 (dbRefResolver, 새로운 MongoMappingContext ()); 및 SimpleMongoDbFactory (새 몽고 (), "databaseName을"); 새로운 SimpleMongoDbFactory (새 MongoClient (), 데이터베이스)에 찬성 ;.

    그래서, 사용 중단 경고없이 내 마지막 작업 대답은 :

    @Configuration
    public class SpringMongoConfig {
    
        @Value("${spring.data.mongodb.database}")
        private String database;
    
        @Autowired
        private MongoDbFactory mongoDbFactory;
    
        public @Bean MongoDbFactory mongoDBFactory() throws Exception {
            return new SimpleMongoDbFactory(new MongoClient(), database);
        }
    
        public @Bean MongoTemplate mongoTemplate() throws Exception {
    
            DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
    
            // Remove _class
            MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
    
            return new MongoTemplate(mongoDBFactory(), converter);
    
        }
    
    }
    

    이없이 사용 중단 경고와 함께 깨끗한 클래스를하고 싶은 사람들에게 도움이되기를 바랍니다.

  6. ==============================

    6.이것은 내 하나의 라인 솔루션입니다 :

    이것은 내 하나의 라인 솔루션입니다 :

    @Bean 
    public MongoTemplate mongoTemplateFraud() throws UnknownHostException {
    
      MongoTemplate mongoTemplate = new MongoTemplate(getMongoClient(), dbName);
      ((MappingMongoConverter)mongoTemplate.getConverter()).setTypeMapper(new DefaultMongoTypeMapper(null));//removes _class
      return mongoTemplate;
    }
    
  7. ==============================

    7.나는이 문제를 오랜 시간 고생. 나는 mkyong의 접근 방식을 따라하지만 난 (자바 8에서 어떤 JSR310 클래스)를 LOCALDATE 속성을 도입 할 때 나는 다음과 같은 예외를 받았습니다 :

    나는이 문제를 오랜 시간 고생. 나는 mkyong의 접근 방식을 따라하지만 난 (자바 8에서 어떤 JSR310 클래스)를 LOCALDATE 속성을 도입 할 때 나는 다음과 같은 예외를 받았습니다 :

    org.springframework.core.convert.ConverterNotFoundException:
    No converter found capable of converting from type [java.time.LocalDate] to type [java.util.Date]
    

    해당 컨버터 org.springframework.format.datetime.standard.DateTimeConverters은 스프링 4.1의 일부이며 봄 데이터 MongoDB를 1.7에서 참조됩니다. 나는 최신 버전을 사용하는 경우에도 컨버터는 뛰어하지 않았다.

    이 솔루션은 기존의 MappingMongoConverter를 사용하고 단지 새로운 DefaultMongoTypeMapper을 (mkyong의 코드는 주석 아래) 제공하는 것이 었습니다 :

    @Configuration
    @EnableMongoRepositories
    class BatchInfrastructureConfig extends AbstractMongoConfiguration
    {
        @Override
        protected String getDatabaseName() {
            return "yourdb"
        }
    
        @Override
        Mongo mongo() throws Exception {
            new Mongo()
        }
    
        @Bean MongoTemplate mongoTemplate()
        {
            // overwrite type mapper to get rid of the _class column
    //      get the converter from the base class instead of creating it
    //      def converter = new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext())
            def converter = mappingMongoConverter()
            converter.typeMapper = new DefaultMongoTypeMapper(null)
    
            // create & return template
            new MongoTemplate(mongoDbFactory(), converter)
        }
    

    요약:

  8. ==============================

    8.당신은 단지 형식 매퍼를 변경을 통해 클래스 정의에 @TypeAlias ​​주석을 추가 할 필요가

    당신은 단지 형식 매퍼를 변경을 통해 클래스 정의에 @TypeAlias ​​주석을 추가 할 필요가

  9. ==============================

    9.

    @Configuration
    public class MongoConfig {
    
        @Value("${spring.data.mongodb.database}")
        private String database;
    
        @Value("${spring.data.mongodb.host}")
        private String host;
    
        public @Bean MongoDbFactory mongoDbFactory() throws Exception {
            return new SimpleMongoDbFactory(new MongoClient(host), database);
        }
    
        public @Bean MongoTemplate mongoTemplate() throws Exception {
    
            MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory()),
                    new MongoMappingContext());
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
    
            MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
    
            return mongoTemplate;
    
        }
    
    }
    
  10. from https://stackoverflow.com/questions/6810488/spring-data-mongodb-mappingmongoconverter-remove-class by cc-by-sa and MIT license