web-dev-qa-db-fra.com

Définir le convertisseur MongoDb par programme

J'essaie d'utiliser un convertisseur personnalisé avec spring-data-mongodb. Je veux le créer par programme, mais j'obtiens l'erreur suivante:

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éfaillant:

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

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

Pour le configurer par programme, vous devez appeler MongoMappingConverter.afterPropertiesSet() avant de l'utiliser. Je l'ai réalisé en lisant le code de MongoTemplate.getDefaultMongoConverter(MongoDbFactory).

Voici un exemple:

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

Juste un avertissement. Je me débattais avec ce problème le spring-data-mongodb 1.5.1.RELEASEusing Java Configuration. Comme certaines classes ont changé, je poste ma solution.

Ajoutez la définition suivante dans votre classe de configuration annotée de @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;
}
15
Trein

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

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

J'ai injecté les valeurs de configuration par défaut afin que je puisse bénéficier des paramètres de configuration 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);
    }
  }
7
helt

Avec l'introduction du package Java.time dans Java 8, j'ai rencontré 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 les 4 de ces options de conversion:

  • DateToLocalDateTimeConverter
  • DateToLocalDateConverter
  • LocalDateTimeToDateConverter
  • LocalDateToDateConverter

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

Ensuite, en incluant cela dans la configuration xml pour la connexion mongodb, j'ai pu travailler dans Java 8 dates avec mongodb (n'oubliez pas 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>
2
Ron Tuffin

Pour moi, il s'agissait d'enregistrer mon convertisseur en tant que lecteur au lieu d'écrivain. Pour résoudre ce problème, vous devez ajouter l'annotation @WritingConverter à votre classe de convertisseur

@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;
    }
}
1
Tidder Jail

Puisque org.springframework.data:spring-data-commons:1.13.3.RELEASE, voici comment créer par programmation 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 (implémentation omise)

class FooWriteConverter implements Converter<Foo, DBObject> { ... }
class FooReadConverter implements Converter<DBObject, Foo> { ... }
1
Johan Sjöberg