Set MongoDb converter programmatically

后端 未结 6 1665
無奈伤痛
無奈伤痛 2020-12-01 08:20

I\'m trying to use a custom converter with spring-data-mongodb. I want to create it programmatically, but I get the following error:

org.springframework.core         


        
相关标签:
6条回答
  • 2020-12-01 08:38

    Since org.springframework.data:spring-data-commons:1.13.3.RELEASE, here's how to programmatically create a MongoTemplate with custom converters

    public MongoTemplate mongoTemplate(String mongoUri) throws Exception {
        MongoDbFactory factory = new SimpleMongoDbFactory(new MongoClientURI(mongoUri));
        CustomConversions conversions = new CustomConversions(
                Arrays.asList(new FooWriteConverter(), new FooReadConverter()));
        MongoMappingContext mappingContext = new MongoMappingContext();
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
        mongoConverter.setCustomConversions(conversions);
        mongoConverter.afterPropertiesSet();
        return new MongoTemplate(factory, mongoConverter);
    }
    

    The converters (implementation omitted)

    class FooWriteConverter implements Converter<Foo, DBObject> { ... }
    class FooReadConverter implements Converter<DBObject, Foo> { ... }
    
    0 讨论(0)
  • 2020-12-01 08:39

    How to customize mongo with custom converters is decribed here in detail:

    http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping-configuration

    I injected the default configuration values so i can benefit from the application.properties configuration settings.

      @Configuration
      public class MongoConfiguration extends AbstractMongoConfiguration {
        @Value("${spring.data.mongodb.database:test}")
        String database;
    
        @Value("${spring.data.mongodb.host:localhost}:${spring.data.mongodb.port:27017}")
        String host;
    
        @Override
        protected String getDatabaseName() {
          return database;
        }
    
        @Override
        public Mongo mongo() throws Exception {
          return new MongoClient(host);
        }
    
        @Bean
        @Override
        public CustomConversions customConversions() {
          List<Converter<?, ?>> converterList = new ArrayList<Converter<?, ?>>();
          converterList.add(new MongoColorWriter());
          converterList.add(new MongoColorReader());
          return new CustomConversions(converterList);
        }
      }
    
    0 讨论(0)
  • 2020-12-01 08:42

    For me it was registering my converter as a reader instead of a writer. To fix that you need to add the @WritingConverter annotation to your converter class

    @Component
    @WritingConverter
    public class NoteWriterConverter implements Converter<Note, DBObject> {
    
    @Override
    public DBObject convert(Note source) {
        DBObject obj = new BasicDBObject();
    
        obj.put("title", source.getTitle());
        obj.put("reviewDate", source.getReviewDate());
    
        obj.removeField("_class");
        return obj;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 08:47

    This answer may be a little late for the OP, but I just ran into the same problem today and found a solution...

    To set it up programmatically, you need to call MongoMappingConverter.afterPropertiesSet() before you use it. I realized this from reading the code for MongoTemplate.getDefaultMongoConverter(MongoDbFactory).

    Here's an example:

    MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory, context);
    converter.setTypeMapper(mapper);
    converter.setCustomConversions(new CustomConversions(
            Arrays.asList(
                    new TimeZoneReadConverter(),
                    new TimeZoneWriteConverter()
            )
    ));
    converter.afterPropertiesSet();
    MongoTemplate template = new MongoTemplate(mongoDbFactory, converter);
    
    0 讨论(0)
  • 2020-12-01 08:47

    Just a heads up. I was struggling with that problem on spring-data-mongodb 1.5.1.RELEASEusing Java Configuration. As some classes have changed, I'm posting my solution.

    Add the following definition in your configuration class annotated with @Configuration:

    @Bean
    public Mongo mongo() throws Exception {
        MongoPropertiesResolver resolver = mongoResolver();
        return new MongoClient(resolver.getUrl());
    }
    
    @Bean
    public MongoDbFactory mongoDbFactory() throws Exception {
        return new SimpleMongoDbFactory(mongo(), "database");
    }
    
    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory(), mongoConverter());
    }
    
    @Bean
    public CustomConversions customConversions() {
        List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
        converters.add(new TimeZoneReadConverter());
        converters.add(new TimeZoneReadConverter());
        return new CustomConversions(converters);
    }
    
    @Bean
    public MappingMongoConverter mongoConverter() throws Exception {
        MongoMappingContext mappingContext = new MongoMappingContext();
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
        MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
        mongoConverter.setCustomConversions(customConversions());
        return mongoConverter;
    }
    
    0 讨论(0)
  • 2020-12-01 08:52

    With the introduction of the java.time package in java 8 I ran into a similar issue using the new LocalDate and LocalDateTime classes in the new package. This is how I solved it:

    I wrote a converter for all 4 of these conversion options:

    • DateToLocalDateTimeConverter
    • DateToLocalDateConverter
    • LocalDateTimeToDateConverter
    • LocalDateToDateConverter

    Here is an example

    public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
    
        @Override 
        public LocalDateTime convert(Date source) { 
            return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault()); 
        }
    }
    

    Then by including this in the xml configuration for the mongodb connection I was able to work in java 8 dates with mongodb (remember to add all the converters):

    <mongo:mapping-converter>
        <mongo:custom-converters>
            <mongo:converter>
                <bean class="package.DateToLocalDateTimeConverter" />
            </mongo:converter>
        </mongo:custom-converters>
    </mongo:mapping-converter>
    
    0 讨论(0)
提交回复
热议问题