-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolving generic enum types (Enum<T>) in nested bean properties #27760
Comments
Thank you for the attention. Is it worth investigating a way to determine the target class based on the field's declaration? |
Thank you for the detailed report. However, we would prefer to have that code in a complete sample with minimal dependencies (i.e. no lombok, Spring Security, or other unrelated libraries). Something that we can unzip or git clone, build, and deploy, and that reproduces the problem. |
If you want your issue to be considered, please try to provide a more focused description. A snippet of a test class with 10 methods and 200 lines of code is just not helpful. |
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed. |
Repository available at https://github.com/djechelon/spring-poc-27760 The repository contains a test controller (which basically does nothing) and a test class Please note that while discussing about enums, I have also implemented an interesting test about As stated in the original post, you will find that:
About item 2, there is yet another test The ultimate goal of the |
@djechelon I've looked at the repository and played a little bit with it and I am afraid we're in the same state as what Rossen described above. It looks like the sample as a lot of unnecessary noise. Can you please trim it down so that it's obvious what you're trying to do? |
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed. |
Okay, let me try to summarize and update the repository whith what's important. Since then, I have changed job and I don't have any more business interest in this Goal is to have Spring read query string parameters into a complex object. In the old business scenario, it was a filter object for queries. Sample requests include
By design, I leverage a generic I am having problems with enums in particular. I have added a test case in which you can see that if you POST the filter and let Jackson handle it, it will decode it fine (I have left only String filter and Enum filter in the sample repository). Jackson decodes string literal Spring REST does not decode that literal into an enum, but rather reflects
If I try to get the "eq" value for constructing a filter in runtime code, I will get a ClassCastException. Repo updated |
@rstoyanchev @snicoll Maybe the difference of behavior could be related to the fact that in |
The difference comes from every nested bean being independently bound: Once the outer We can try to revisit this for 6.2 but it won't be straightforward since standard JavaBeans introspection operates against a Class. |
Correct. Jackson works against a |
Affects: 5.3.10
I am experiencing a problem with MVC method argument resolving in GET invocations. I have already reduced my problem to a bunch of classes and a reproducible example using Spring Test.
The idea is that I have a Filter Framework that heavily relies on generics. The first part of the FF, the one we are dealing with, is MVC argument resolution. The second part is translation into ORM predicates, which is out of scope.
Let's not talk about
IntegerFilter
andLongFilter
, let's focus on a genericEnumFilter
I know that Java erases generic types to the lower bound (
java.lang.Enum
), but the generic information is preserved in Java 11 when applied to a field.Consider this particular filter
Consider the following controller:
Now consider the following tests
The problems here
If I declare (even as a static class) a boilerplate filter class bound to the
AmlObjectType
enum, it works. But if I declare a field asEnumFilter<AmlObjectType>
Spring is unable to resolve the property as it thinks the property value should be cast toEnum
, which is the generic bound ofEnumFilter<T extends Enum<T>>
.E.g. using
GET /api?exampleObjectTypeEnum.eq=CONTROL
works, usingGET /api?exampleObjectTypeEnumGeneric.eq=CONTROL
orGET /api?exampleObjectTypeSimple.eq=CONTROL
does not.It would not happen using JSON POST with Jackson Object Mapper.
In this case, using
SimpleFilter<AmlObjectType>
results in Spring setting the value CONTROL (String) as an Object into the property, which fails the assertion because I am comparing an enum with a string.In this case, Spring detects the target type as
Enum
, and can't cast CONTROL to the root Enum classThis succeeds because target property is of type
AmlObjectTypeFilter
which is bound directly toAmlObjectType
Debugging
I also found that Spring could be aware of the actual generic type of a field at some point. I was spelunking deep into
Introspector
and found the belowThis shows that the generic type is known for the field, but then looks like Spring ignores the property generic binding and works only on the (raw....) type.
At
AbstractNestablePropertyAccessors#
variable ph has now lost any information about the generic binding of the filter class's property.And at line 590 the "target class" is now just
Enum
.Porkarounds
The text was updated successfully, but these errors were encountered: