spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

Support nested Java records for AbstractNestablePropertyAccessor

Open benneq opened this issue 2 years ago • 1 comments

Affects: 6.0.0.M5 (but also 5.x)


I'm trying to get an immutable representation of the query parameters in my @RestController, like this:

@RestController
public class MyController {
	
	@RequestMapping("/foo")
	public void foo(A a) {
	}
	
	record A(String s, B b) {
	}

	record B(Integer i) {
	}
}

For single-level query params this works as expected: GET /foo?s=xyz

But as soon as I try to set b.i using GET /foo?b.i=42 it will throw an exception, because AbstractNestablePropertyAccessor is looking for a default constructor:

java.lang.NoSuchMethodException: com.example.demo.MyController$B.<init>()
	at java.base/java.lang.Class.getConstructor0(Class.java:3585) ~[na:na]
	at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2754) ~[na:na]
	at org.springframework.beans.AbstractNestablePropertyAccessor.newValue(AbstractNestablePropertyAccessor.java:910) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.beans.AbstractNestablePropertyAccessor.createDefaultPropertyValue(AbstractNestablePropertyAccessor.java:883) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.beans.AbstractNestablePropertyAccessor.setDefaultValue(AbstractNestablePropertyAccessor.java:870) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.beans.AbstractNestablePropertyAccessor.getNestedPropertyAccessor(AbstractNestablePropertyAccessor.java:842) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyAccessorForPropertyPath(AbstractNestablePropertyAccessor.java:816) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:257) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:104) ~[spring-beans-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:889) ~[spring-context-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.validation.DataBinder.doBind(DataBinder.java:780) ~[spring-context-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:207) ~[spring-web-6.0.0-M5.jar:6.0.0-M5]
	at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:129) ~[spring-web-6.0.0-M5.jar:6.0.0-M5]

Thanks for your help!

benneq avatar Aug 22 '22 20:08 benneq

@jhoeller this looks like it should be covered/superseded by #20806? Maybe just an extra comment there to ensure it works for records too.

rstoyanchev avatar Oct 24 '22 11:10 rstoyanchev

This is covered by #20806.

rstoyanchev avatar Jun 27 '23 20:06 rstoyanchev