Micronaut-core: Validation is not working

Created on 11 Nov 2018  路  7Comments  路  Source: micronaut-projects/micronaut-core

Task List

Create a new micronaut kotlin app
Create a controller
Create a data object
Add validation to the controller
Try to validate request
Validation is failing

Steps to Reproduce

  1. mn create-app mntest --features=kotlin
  2. cd mntest
  3. Add Person and PersonController classes
  4. Add the hibernate-validator gradle dependency
  5. Gradle run
  6. Send a simple post request to the http://localhost:8080/persons endpoint
    {"name": ""}

Expected Behaviour

The request should fail with a validation error

Actual Behaviour

Request does not fail

Environment Information

  • Operating System: Mac OS 10.13.6
  • Micronaut Version: 1.0.0
  • JDK Version: 1.8.0_101

Example Application

https://github.com/satb/mntest

notabug kotlin

All 7 comments

You need to replace the data class with:

package mntest

import javax.validation.constraints.NotEmpty

class Person {
    @NotEmpty
    var name = ""
}

DataClasses

Data classes cannot be abstract, open, sealed or inner;

Micronaut provides a compile-time AOP API that does not use reflection. When you use any Micronaut鈥檚 AOP Advice, it creates a subclass at compile-time to provide the AOP behaviour. Such as the AOP validation behaviour.

See section: 13.3.2 Kotlin and AOP Advice

@sdelamo - I tried a normal class as well like this

class Person(@NotEmpty val name: String)

This one does not validate either.

However, the way you suggested works

class Person {
    @NotEmpty
    var name = ""
}

What is the difference between the two definitions of the class that it works in one style and not the other?

Also - why don't we get a compilation error if the Aspect cannot be created at compile time? It just compiles fine even with the data class.

Good question, we are just using Hibernate validator for validation, so maybe more a question for the Hibernate validator team

The way validation works with kotlin data classes is to use get.
data class Person(@get:NotEmpty val name: String = "")

I updated the test app repo with little bit of additional validation. I added a DateOfBirth to the Person class. Now if we run the application, strangely, if we input an invalid year for the date of birth, it validates correctly. Input an invalid month or date, it lets it through. Any clue as to what might be going wrong?

import javax.validation.constraints.Max
import javax.validation.constraints.Min

data class DateOfBirth(
  @get:Min(1) @Max(12) val month:String,
  @get:Min(1) @Max(31) val date:String,
  @get:Min(1950) @Max(2018) val year:String
)
import javax.validation.constraints.NotEmpty
import javax.validation.constraints.Min
import javax.validation.constraints.Max
import javax.validation.Valid

data class Person (
  @get: NotEmpty
  val name: String = "",
  @get:Valid val dateOfBirth: DateOfBirth = DateOfBirth("", "", "")
)

With this input, it just goes through fine even though the month and the date are wrong

{
    "persons": [
        {
            "name": "Joe", 
          "dateOfBirth": {"month": "15", "date": "32", "year": "1953"}
        }
  ]
}

Response from the controller is:

Hi Joe! Your date of birth is 15-32-1953

With this input, the year is wrong and it catches the year input as invalid but not the date or the month

{
    "persons": [
        {
            "name": "Joe", 
          "dateOfBirth": {"month": "15", "date": "32", "year": "1903"}
        }
  ]
}

Response is

{
    "_links": {
        "self": {
            "href": "/persons",
            "templated": false
        }
    },
    "message": "req.persons[0].dateOfBirth.year: must be greater than or equal to 1950"
}

https://github.com/satb/mntest/tree/master/src/main/kotlin/mntest

Please read on hibernate validation, refer to the annotations. min, max is for the string length. If you want min and max to work the way you want it has to be a number. It's better to use java.util.Date or LocalDate and use the corresponding validation for dates.

@zulq - This is just a test and it isn't working as expected and hence I am putting it out there. Min and Max are not for string length as you expect. It is to check if something is above or below a certain value. In the case of month, you can specify that month should be no less than 1 and no more than 12. Did you try running the test project I provided? It ain't working as expected.

See Table 2.1
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html-single/Hibernate_Validator_Reference_Guide/index.html

Was this page helpful?
0 / 5 - 0 ratings