-
Notifications
You must be signed in to change notification settings - Fork 6
Description
For one of our projects, I had the following structure inside one of the persistable entities:
@Transient
private final Map<UUID, List<String>> entityIdsWithSomething = new ConcurrentHashMap<>(); // Only for CSV import of XXX
When accessing the /constraints
endpoint, which is provided by BeanConstraintController
, the following error is thrown:
10-09-2020 11:14:21.282 ERROR [080-exec-1] l._42.xxx.config.web.errorhandling.ControllerExceptionAdvice:122 Handling request, for [nl._42.jarb.constraint.metadata.BeanConstraintController#describeAll()], resulted in the following exception.
java.lang.ClassCastException: class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to class java.lang.Class (sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl and java.lang.Class are in module java.base of loader 'bootstrap')
at nl._42.jarb.constraint.metadata.BeanConstraintDescriptor.describeBean(BeanConstraintDescriptor.java:85)
at nl._42.jarb.constraint.metadata.BeanConstraintService.describe(BeanConstraintService.java:56)
at nl._42.jarb.constraint.metadata.BeanConstraintService.describeAll(BeanConstraintService.java:30)
at nl._42.jarb.constraint.metadata.BeanConstraintController.describeAll(BeanConstraintController.java:25)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
This seems to be caused by
Class<?> valueType = (Class<?>) getGenericTypes(field)[1]; |
Which assumes that parameterizedType.getActualTypeArguments()
always returns a Class
, but this is not the case if another generic type is present (in this case: List<String>
).
See https://stackoverflow.com/questions/24829146/classcastexceptionjava-lang-class-cannot-be-cast-to-java-lang-reflect-parameter in which this is explained.
Something should be changed in the BeanConstraintsDescriptor
to handle cases like this (or as a quick fix: if the field is annotated with @Transient
, then simply skip processing it)