Skip to content
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

Add support for non-public record declarations #27437

Closed
joshlong opened this issue Sep 19, 2021 · 3 comments
Closed

Add support for non-public record declarations #27437

joshlong opened this issue Sep 19, 2021 · 3 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@joshlong
Copy link
Member

joshlong commented Sep 19, 2021

This might be possible, and I just couldn't find the documentation or make it work, but in essence it feels like it should be possible to bind form payloads to a Java 14 record via the constructor

record Greeting(String name){}

@Controller 
class GreetingsMvcController {

  @PostMapping ("/greetings") 
  void submit (@ModelAttribute Greeting greeting) { 
    System.out.println( "the name is " + greeting.name()) ; 
  }
}

Thanks for your consideration, and I apologize if this has already been solved.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Sep 19, 2021
@odrotbohm odrotbohm changed the title Please support records for @ModelBinding in Spring MVC Please support records for @ModelAttribute in Spring MVC Sep 20, 2021
@odrotbohm
Copy link
Member

This is a visibility issue because Greeting is package protected. If you make it public, the binding works as expected. I've previously asked for this in #22600 (this comment in particular).

@jhoeller jhoeller self-assigned this Sep 20, 2021
@jhoeller
Copy link
Contributor

It turns out that this is indeed a visibility issue since the Java compiler generates the implicit record constructor as package-visible if the record type itself is also package-visible. We do not insist on the type itself being public, just on the constructor being public; a custom package-visible data class with a public constructor works fine already.

Since constructor visibility is not specifically declared by the user in case of a record, this is a rather unpleasant case. I've revisited our BeanUtils.getResolvableConstructor algorithm to keep looking for a single public constructor first, but then in case of no public constructors at all to look for a single non-public constructor with arguments before resorting to a default constructor.

I'll repurpose this issue accordingly. Our general advice remains that record types should be declared public, but anyway, we'll leniently handle such non-public scenarios as of 5.3.11 - for record types as well as custom data classes with a single non-public constructor. That said, method visibility still follows JavaBean setter/getter rules; we're not going to bend those for 5.3.x at all.

@jhoeller jhoeller changed the title Please support records for @ModelAttribute in Spring MVC Please support non-public record declarations for @ModelAttribute in Spring MVC Sep 22, 2021
@jhoeller jhoeller added in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Sep 22, 2021
@jhoeller jhoeller added this to the 5.3.11 milestone Sep 22, 2021
@snicoll snicoll changed the title Please support non-public record declarations for @ModelAttribute in Spring MVC Add support for non-public record declarations Sep 22, 2021
@jhoeller jhoeller added the in: data Issues in data modules (jdbc, orm, oxm, tx) label Sep 22, 2021
@jhoeller
Copy link
Contributor

jhoeller commented Sep 22, 2021

Addressing this at BeanUtils.getResolvableConstructor level affects DataClassRowMapper as well. I'm taking the opportunity to add actual record tests to both spring-webmvc and spring-jdbc accordingly (for 6.0 whereas 5.3.x just has tests for record-like custom data classes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants