I tried to bump my project up to the most recent Spring Boot 2.0.0 milestone (M4 at the moment of this writing) and I keep getting an exception for a missing Converter (ZonedDateTime to java.util.Date) although it's clearly configured - to me at least. Here's the code and stacktrace:
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import java.time.ZonedDateTime;
import java.util.Date;
@Component
public class ZonedDateTimePersistenceConverter implements Converter<ZonedDateTime, Date> {
@Nullable
@Override
public Date convert(ZonedDateTime source) {
return Date.from(java.time.ZonedDateTime.now().toInstant());
}
}
When calling the respective Spring Data REST endpoint I get:
2017-09-17 21:07:53.634 ERROR 1894 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]] with root cause
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.time.ZonedDateTime] to type [java.util.Date]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.lambda$getLastModifiedInMilliseconds$5(HttpHeadersPreparer.java:123) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_131]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.getLastModifiedInMilliseconds(HttpHeadersPreparer.java:123) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.HttpHeadersPreparer.prepareHeaders(HttpHeadersPreparer.java:83) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.ResourceStatus.getStatusAndHeaders(ResourceStatus.java:71) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at org.springframework.data.rest.webmvc.RepositoryEntityController.lambda$getItemResource$3(RepositoryEntityController.java:337) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_131]
at org.springframework.data.rest.webmvc.RepositoryEntityController.getItemResource(RepositoryEntityController.java:333) ~[spring-data-rest-webmvc-3.0.0.RC3.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:869) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:775) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:981) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:915) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855) ~[spring-webmvc-5.0.0.RC4.jar:5.0.0.RC4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
...
I've already done some research like debugging and inspecting the GenericConversionService, DefaultConversionService, manually adding it to the converter registry via WebMvcConfigurerAdapter... to no avail.
Any idea where I should look further or what's going here? Thanks a lot in advance! :)
Edit 1: Additional information to what I've tried and where it's happening. Adding the converter manually didn't help, like so:
@Component
public class AdditionalConverterConfig extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new ZonedDateTimePersistenceConverter());
}
}
Funnily, the error occurs when I try to access the URI to one of the entities exposed via a Spring Data REST repository (entity is called "Posting", btw), like so:
@RepositoryRestResource(collectionResourceRel = "postings", path = "postings")
public interface PostingRepository extends PagingAndSortingRepository<Posting, Long> {
}
A GET for /api/postings works just fine, listing the first collection page as expected. GET /api/postings/1 however does not. The only critical ZonedDateTime properties in the entity are from its mapped superclass:
@CreatedDate
protected ZonedDateTime createdAt;
@LastModifiedDate
protected ZonedDateTime modifiedAt;
In the listing they appear just fine - in the detail view... not so much ;)