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

Bean Validation does not work with Kotlin [SPR-16297] #20844

Closed
spring-issuemaster opened this issue Dec 13, 2017 · 5 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Dec 13, 2017

Michael Böckling opened SPR-16297 and commented

I made a test case: https://github.com/MrBuddyCasino/spring-validator-test

Execute the following test case: de.codecentric.controller.AccountControllerShould

Expected result:
the request should fail with a BadRequest, the unit test should fail

Actual result:
the request succeeds, the unit test fails

I made some tests and this version works:

class CreateUserDTO {

    @Email
    var email: String? = null

    @Size(min = 8)
    var password: String? = null
}

This version does not:

class CreateUserDTO(
        @Email
        val email: String,

        @Size(min = 8)
        val password: String) {
}

This version does not:

data class CreateUserDTO(
        @Email
        val email: String,

        @Size(min = 8)
        val password: String) {
}

So it seems to be a problem with immutable Kotlin properties. Spring Boot 2 advertises Kotlin support, so this should work IMHO.

also see: spring-projects/spring-boot#11343


Affects: 5.0.2

Reference URL: https://github.com/MrBuddyCasino/spring-validator-test

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 14, 2017

Michael Böckling commented

The plot thickens. Decompiling

data class CreateUserDTO(
        @Email
        val email: String
)

leads to

public final class CreateUserDTO {
   @NotNull
   private final String email;

   @NotNull
   public final String getEmail() {
      return this.email;
   }

while decompiling

data class CreateUserDTO(
        @get:Email
        val email: String
)

will give you

public final class CreateUserDTO {
   @NotNull
   private final String email;

   @Email
   @NotNull
   public final String getEmail() {
      return this.email;
   }
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 14, 2017

Michael Böckling commented

Ok, so I think we've got this solved.
The reason is: if you annotate something inside the constructor only the constructor parameter is annotated. Not intuitive, but makes sense. Not sure how to proceed here.

Credits got to Lovis Möller for decompiling stuff and finding the root cause.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 14, 2017

Sébastien Deleuze commented

Notice this is exactly what describes the SO link provided by Stéphane Nicoll on the original Boot issue. I will add a mention to it in the Kotlin documentation.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 14, 2017

Michael Böckling commented

Seems this link was added shortly afterwards to the comment, so I missed it. Sorry for the trouble.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 14, 2017

Sébastien Deleuze commented

Out of luck you missed it, since indeed that's not intuitive. I have updated the documentation via this commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.