Spring Data MongoDB doesn't see enabled by default Joda-Time converter
-
21-12-2019 - |
Question
I try to just save a document with org.joda.time.DateTime field from Joda-Time.
@Document
public class JodaDoc {
@Id
private BigInteger id;
private String dateAsString;
private DateTime date;
public JodaDoc(String dateAsString, DateTime date) {
this.dateAsString = dateAsString;
this.date = date;
}
public BigInteger getId() { return id; }
public String getDateAsString() { return dateAsString; }
public DateTime getDate() { return date; }
}
Standard application config using AbstractMongoConfiguration from spring-data-mongodb:
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
A test which explicit uses AppConfig class (with Spock, but internally mechanisms provided by spring-test are used):
@ContextConfiguration(classes = AppConfig)
class JodaDocRepositorySpec extends Specification {
@Autowired
private JodaDocRepository jodaDocRepository
def "save document with DateTime"() {
given:
def jodaDoc = new JodaDoc(DateTime.now())
when:
def savedJodaDoc = jodaDocRepository.save(jodaDoc)
then:
savedJodaDoc.id
}
}
Joda-Time converters in Spring Data MongoDB (and also in Spring Core itself) should be enabled by default when Joda-Time jar is on a classpath. Unfortunately my test fails with:
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type org.joda.time.DateTime to type java.util.Date
I tried to add DefaultFormattingConversionService:
@Bean
public ConversionService conversionService() {
return new DefaultFormattingConversionService();
}
ConversionServiceFactoryBean and a few other things with no effect. I wasn't able to find an answer on StackOverflow.
Question. Why Spring Data MongoDB doesn't see a standard org.joda.time.DateTime -> java.util.Date
conveter?
Solution
It took me some time and I want to share the solution with others.
I created a small quickstart application and wasn't able to reproduce the issue. At the end I discovered that the problem was a missing @Configuration
annotation in my configuration class. With:
@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }
it just works fine.
I often have omitted @Configuration
for the configuration class when it is explicit registered in the context (by classes in @ContextConfiguration
or a register()
method in AnnotationConfigWebApplicationContext)
. The classes were processed anyway and all declared beans are found. It is sometimes useful to not use @Configuration
to prevent detecting by a component scan when there are 2 similar configuration classes in the same packages in a test context used by different tests. It generated an another question as I am not sure if it is a desired behavior.