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 +
'}';
}
}
With the introduction of the java.time package in java 8 I ran into a similar issue using the new LocalDate and LocalDateTime classes in the new package. This is how I solved it:
I wrote a converter for all 4 of these conversion options:
Here is an example
Then by including this in the xml configuration for the mongodb connection I was able to work in java 8 dates with mongodb (remember to add all the converters):
Since
org.springframework.data:spring-data-commons:1.13.3.RELEASE
, here's how to programmatically create aMongoTemplate
with custom convertersThe converters (implementation omitted)
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 forMongoTemplate.getDefaultMongoConverter(MongoDbFactory)
.Here's an example:
Just a heads up. I was struggling with that problem on
spring-data-mongodb 1.5.1.RELEASE
using Java Configuration. As some classes have changed, I'm posting my solution.Add the following definition in your configuration class annotated with
@Configuration
:How to customize mongo with custom converters is decribed here in detail:
http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping-configuration
I injected the default configuration values so i can benefit from the application.properties configuration settings.
For me it was registering my converter as a reader instead of a writer. To fix that you need to add the @WritingConverter annotation to your converter class