2012-12-08 14 views
17

Próbuję użyć niestandardowego konwertera z wiosennymi danymi-mongodb. Chcę utworzyć go programowo, ale pojawia się następujący błąd:Ustaw programowo konwerter MongoDb

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) 
.... 
.... 

Poniżej znajduje się kod braku urywek:

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); 

A oto moje klasy konwerter:

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. 
    } 
} 

Klasa, którą próbuję utrwalić, wygląda następująco:

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 + 
       '}'; 
     } 
} 

Odpowiedz

18

Ta odpowiedź może być trochę za późno na PO, ale po prostu wpadł na ten sam problem dzisiaj i znalazł rozwiązanie ...

go skonfigurować programowo, trzeba zadzwonić MongoMappingConverter.afterPropertiesSet() przed użyciem. Zrozumiałem to czytając kod dla MongoTemplate.getDefaultMongoConverter(MongoDbFactory).

Oto przykład:

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

końcu udało mi się, aby to sprawdzić, i to działało doskonale. Wielkie dzięki! – Daniel

+1

Dziękuję bardzo! Jak widziałem '.afterPropertiesSet();' w jednostce testów danych wiosennych nie zwróciłem na to wystarczającej uwagi ... – Zarathustra

+0

To faktycznie uratowało mi godziny, dzięki! : D – ArcanisCz

0

Wraz z wprowadzeniem pakietu java.time w java 8 wpadłem podobnego problemu za pomocą nowych klas LOCALDATE i LocalDateTime w nowym opakowaniu. ten sposób Rozwiązałem go:

pisałem konwerter dla wszystkich 4 z tych opcji konwersji:

  • DateToLocalDateTimeConverter
  • DateToLocalDateConverter
  • LocalDateTimeToDateConverter
  • LocalDateToDateConverter

Tutaj to przykład

public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> { 

    @Override 
    public LocalDateTime convert(Date source) { 
     return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault()); 
    } 
} 

Następnie poprzez uwzględnienie tego w konfiguracji xml do podłączenia MongoDB byłem w stanie pracować w Java 8 dat z MongoDB (pamiętaj, aby dodać wszystkie konwertery):

<mongo:mapping-converter> 
    <mongo:custom-converters> 
     <mongo:converter> 
      <bean class="package.DateToLocalDateTimeConverter" /> 
     </mongo:converter> 
    </mongo:custom-converters> 
</mongo:mapping-converter> 
11

prostu głowy do góry . Zmagałem się z tym problemem na spring-data-mongodb 1.5.1.RELEASE przy użyciu konfiguracji Java. Ponieważ niektóre klasy się zmieniły, publikuję moje rozwiązanie.

Dodaj następującą definicję w swojej klasie konfiguracji z dopiskiem @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; 
} 
+3

Skąd pochodzi 'mongoResolver()'? –

+1

Konstruktor SimpleMongoDbFactory (Mongo, String) jest przestarzały - używam Spring Boot 1.3.2 –

+0

Dzięki za przykład kodu, pomogło mi to skonfigurować niektóre niestandardowe konwertery podczas próby zestawienia niektórych testów jednostkowych za pomocą Fongo. –

2

Jak dostosować Mongo z niestandardowych przetworników jest to opisano tutaj w szczegółach:

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

Wstrzyknąłem domyślną konfigurację wartości, dzięki czemu mogę korzystać z ustawień konfiguracji application.properties.

@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

Udostępniony link był pomocny. –

0

Od org.springframework.data:spring-data-commons:1.13.3.RELEASE, oto jak programowo utworzyć MongoTemplate z niestandardowymi konwerterów

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); 
} 

konwerterów (wdrożenie pominięte)

class FooWriteConverter implements Converter<Foo, DBObject> { ... } 
class FooReadConverter implements Converter<DBObject, Foo> { ... }