The paramName value for the constructor field is available, but is not used during binding on line 256 when binder.convertIfNecessary(value, paramTypes[i], methodParam) is called. When propertyEditorRegistry.findCustomEditor(requiredType, propertyName) is finally called in the TypeConverterDelegate, it is with a null value for the propertyName field, so any custom field editors will not be found.

Affects: 5.3.16


Comment From: sbrannen

Hi @seabamirum,

Thanks for creating your first issue for the Spring Framework. 👍

Is the behavior you are describing something that worked prior to 5.3.16?

Also, please provide a simple application or test case that reproduces the behavior you are describing (for example, as a GitHub project or ZIP file attached to this issue that we can download and run locally).

Comment From: jhoeller

From a quick glance, it looks like we never supported this, taking the constructor parameter names into account for value retrieval but not for type conversion purposes. So only setter-derived property names are being exposed for PropertyEditor resolution, not constructor parameter names. We can certainly try to redefine this for exposing constructor parameter names there as well.

Comment From: spring-projects-issues

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.

Comment From: seabamirum

I'm sorry I could not make a test case, because there's no straightforward way to get an instance of WebDataBinder without a target object that is already instantiated.

However I think allowing custom property editors for constructor fields without setters would be a welcome improvement, if only for consistency in the framework. Right now it's not clear why it doesn't work, and I don't think it is documented.

In my case I wanted to use a custom PasswordEncodingPropertyEditor to immediately encode the password in Spring Security's User object on signup. The only workaround that I found was to make a dummy object for binding, and then call the User.builder() method in the controller with the bound fields of that object.