2012-12-08 6 views
17

J'essaie d'utiliser un convertisseur personnalisé avec spring-data-mongodb. Je veux créer un programme, mais je reçois l'erreur suivante:Définir le convertisseur MongoDb par programme

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

Voici l'extrait de code défaut:

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

Et voici mes cours de conversion:

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

La classe que j'essaie de persister ressemble à ceci:

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

Répondre

18

Cette réponse peut être un peu en retard pour l'OP, mais je viens de croiser le même problème aujourd'hui et trouvé une solution ...

Pour le configurer par programme, vous devez appeler MongoMappingConverter.afterPropertiesSet() avant de l'utiliser. J'ai réalisé cela à la lecture du code pour MongoTemplate.getDefaultMongoConverter(MongoDbFactory).

Voici un exemple: Avec l'introduction du paquet java.time

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

J'ai finalement eu le temps de le tester, et cela a fonctionné à la perfection. Merci beaucoup! – Daniel

+1

Merci beaucoup! Comme je l'ai vu '.afterPropertiesSet();' dans les tests unitaires de données de printemps je n'y ai pas prêté assez d'attention ... – Zarathustra

+0

Cela m'a sauvé des heures, merci! : D – ArcanisCz

0

en java 8 je suis tombé sur un problème similaire en utilisant les nouvelles classes LOCALDATE et LocalDateTime dans le nouveau package. Voici comment je l'ai résolu:

j'ai écrit un convertisseur pour tous les 4 de ces options de conversion:

  • DateToLocalDateTimeConverter
  • DateToLocalDateConverter
  • LocalDateTimeToDateConverter
  • LocalDateToDateConverter

ici est un exemple

public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> { 

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

Puis en incluant ce dans la configuration XML pour la connexion MongoDB j'ai pu travailler en Java 8 dates avec MongoDB (souvenez-vous d'ajouter tous les convertisseurs):

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

Juste un heads-up . Je luttais avec ce problème sur spring-data-mongodb 1.5.1.RELEASE en utilisant Java Configuration. Comme certaines classes ont changé, je poste ma solution.

Ajouter la définition suivante dans votre classe de configuration annotée avec @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

D'où vient mongoResolver() '? –

+1

Le constructeur SimpleMongoDbFactory (Mongo, String) est obsolète - J'utilise Spring Boot 1.3.2 –

+0

Merci pour l'exemple de code, cela m'a aidé à configurer des convertisseurs personnalisés lorsque j'ai essayé de mettre en place des tests unitaires en utilisant Fongo. –

2

Comment personnaliser mongo avec des convertisseurs personnalisés est decribed ici en détail:

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

Je réinjecté la configuration par défaut valeurs pour que je puisse bénéficier des paramètres de configuration d'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

Le lien partagé a été utile. –

0

Depuis org.springframework.data:spring-data-commons:1.13.3.RELEASE, voici comment créer par programme un MongoTemplate avec des convertisseurs personnalisés

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

Les convertisseurs (mise en œuvre omise)

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