query library index full for example ejemplo java mongodb spring-data-mongodb

java - library - mongodb search text



Establecer el convertidor de MongoDb programáticamente (6)

A continuación se describe detalladamente cómo personalizar mongo con convertidores personalizados:

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

Inyecté los valores de configuración predeterminados para poder beneficiarme de los ajustes de configuración de 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); } }

Estoy tratando de usar un convertidor personalizado con spring-data-mongodb. Quiero crearlo programáticamente, pero obtengo el siguiente 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) .... ....

El siguiente es el fragmento de código que falla:

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

Y aquí están mis clases de convertidor:

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 clase que estoy tratando de persistir se ve así:

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


Con la introducción del paquete java.time en java 8, me encontré con un problema similar al usar las nuevas clases LocalDate y LocalDateTime en el nuevo paquete. Así lo resolví:

Escribí un convertidor para las 4 de estas opciones de conversión:

  • DateToLocalDateTimeConverter
  • DateToLocalDateConverter
  • LocalDateTimeToDateConverter
  • LocalDateToDateConverter

Aquí hay un ejemplo

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

Luego, al incluir esto en la configuración xml para la conexión mongodb, pude trabajar en fechas de Java 8 con mongodb (recuerde agregar todos los convertidores):

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


Desde org.springframework.data:spring-data-commons:1.13.3.RELEASE , aquí se explica cómo crear una MongoTemplate con convertidores personalizados mediante programación.

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

Los convertidores (implementación omitida)

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


Esta respuesta puede ser un poco tarde para el OP, pero hoy me encontré con el mismo problema y encontré una solución ...

Para configurarlo programáticamente, debe llamar a MongoMappingConverter.afterPropertiesSet() antes de usarlo. Me di cuenta de esto al leer el código de MongoTemplate.getDefaultMongoConverter(MongoDbFactory) .

Aquí hay un ejemplo:

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


Para mí fue registrar mi convertidor como un lector en lugar de un escritor. Para solucionarlo, debe agregar la anotación @WritingConverter a su clase de convertidor

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


Sólo un heads up. Estaba luchando contra ese problema en spring-data-mongodb 1.5.1.RELEASE utilizando la configuración de Java. Como algunas clases han cambiado, estoy publicando mi solución.

Agregue la siguiente definición en su clase de configuración anotada con @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; }