Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set MongoDb converter programmatically

Tags:

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.convert.ConverterNotFoundException: No converter found capable of     converting from type org.joda.time.LocalDate to type java.lang.String at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:475) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:154) .... .... 

The following is the failing code snippet:

    Mongo mongo = new Mongo();     MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongo, "database");      List<Converter> converters = new ArrayList<>();     converters.add(new LocalDateWriteConverter());     converters.add(new LocalDateReadConverter());     CustomConversions customConversions = new CustomConversions(converters);      MappingContext mappingContext = new SimpleMongoMappingContext();     MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(mongoDbFactory, mappingContext);     mappingMongoConverter.setCustomConversions(customConversions);      MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, mappingMongoConverter);      MongoDbEvent mongoEvent = new MongoDbEvent(new LocalDate(2012, 12, 8));     mongoTemplate.insert(mongoEvent); 

And here are my converter classes:

class LocalDateReadConverter implements Converter<String, LocalDate> {     @Override     public LocalDate convert(String s) {         // Conversion code omitted.     } }  class LocalDateWriteConverter implements Converter<LocalDate, String> {      @Override     public String convert(LocalDate localDate) {         // Conversion code omitted.     } } 

The class I'm trying to persist looks like this:

import org.joda.time.LocalDate;  public class MongoDbEvent {      private String id;     private LocalDate date;      public MongoDbEvent(LocalDate date) {         this.date = date;     }      public String getId() {         return id;     }      public LocalDate getDate() {         return date;     }      @Override     public String toString() {         return "MongoDbEvent{" +                 "id='" + id + '\'' +                 ", date=" + date +                 '}';         } } 
like image 354
Daniel Avatar asked Dec 08 '12 18:12

Daniel


2 Answers

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); 
like image 187
andy Avatar answered Sep 19 '22 15:09

andy


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; } 
like image 37
Trein Avatar answered Sep 17 '22 15:09

Trein