so first of all i could not think of a better title for this question so i\'m open for changes.
I am trying to validate a bean using the bean validation mechanism (JSR-3
Make sure to compile the kotlin code with jvm target 1.8 or greater and enable this feature by providing the -Xemit-jvm-type-annotations
when compiling.
For Spring Boot projects you only have to do the following changes (tested with Spring Boot 2.3.3 and Kotlin 1.4.0):
11
1.4.0
-Xemit-jvm-type-annotations
to the kotlin-maven-plugin
:
kotlin-maven-plugin
org.jetbrains.kotlin
-Xjsr305=strict
-Xemit-jvm-type-annotations
spring
org.jetbrains.kotlin
kotlin-maven-allopen
${kotlin.version}
Sample Project
Rafal G. already pointed out that we could use a custom validator as a workaround. So here's some code:
The Annotation:
import javax.validation.Constraint
import javax.validation.Payload
import kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS
import kotlin.annotation.AnnotationTarget.CONSTRUCTOR
import kotlin.annotation.AnnotationTarget.FIELD
import kotlin.annotation.AnnotationTarget.FUNCTION
import kotlin.annotation.AnnotationTarget.TYPE_PARAMETER
import kotlin.annotation.AnnotationTarget.VALUE_PARAMETER
import kotlin.reflect.KClass
@MustBeDocumented
@Constraint(validatedBy = [NoNullElementsValidator::class])
@Target(allowedTargets = [FUNCTION, FIELD, ANNOTATION_CLASS, CONSTRUCTOR, VALUE_PARAMETER, TYPE_PARAMETER])
@Retention(AnnotationRetention.RUNTIME)
annotation class NoNullElements(
val message: String = "must not contain null elements",
val groups: Array> = [],
val payload: Array> = []
)
The ConstraintValidator:
import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext
class NoNullElementsValidator : ConstraintValidator> {
override fun isValid(value: Collection?, context: ConstraintValidatorContext): Boolean {
// null values are valid
if (value == null) {
return true
}
return value.stream().noneMatch { it == null }
}
}
And finally the updated User class:
data class User(
@field:NotEmpty
@field:NoNullElements
var roles: MutableSet = HashSet()
)
Altough validation works now, the resulting ConstrainViolation is slightly different. For example the elementType
and propertyPath
differs as you can see below.
Java:
Kotlin:
Source is available here: https://github.com/DarkAtra/jsr380-kotlin-issue/tree/workaround
Thanks again for your help Rafal G.