springkotlinbean-validation

Spring Boot bean validator not triggering


I am using the latest stable version of springboot and spring-validator, however the bean validation is not being called at all. Bellow my gradle.kts, Bean and Controller:

plugins {
    java
    id("org.springframework.boot") version "3.2.2"
    id("io.spring.dependency-management") version "1.1.4"
    id("org.jetbrains.kotlin.plugin.spring") version "1.9.22"
    kotlin("plugin.noarg") version "1.9.22"
    kotlin("plugin.jpa") version "1.9.22"
    kotlin("jvm")
}

group = "com.study.alura.challenge"
version = "0.0.1-SNAPSHOT"

java {
}

repositories {
    mavenCentral()
}

dependencies {
    // Spring
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-log4j2")
    developmentOnly("org.springframework.boot:spring-boot-devtools")
    implementation("org.springframework.boot:spring-boot-starter-validation:3.2.2")

    //Database
    implementation("org.flywaydb:flyway-core")
    runtimeOnly("org.postgresql:postgresql")

    //AWS
    implementation("com.amazonaws:aws-java-sdk:1.12.644")

    //Kotlin
    runtimeOnly("org.jetbrains.kotlin:kotlin-reflect:1.9.22")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.16.1")
    implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.1")

    //Testing
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    implementation(kotlin("stdlib-jdk8"))
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.cloud:spring-cloud-dependencies:2023.0.0")
    }
}

configurations {
    all {
        exclude("org.springframework.boot", module = "spring-boot-starter-logging")
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}
kotlin {
    jvmToolchain(21)
}
package com.study.alura.challenge.journeymiles.user.controller

import com.study.alura.challenge.journeymiles.user.dto.request.CreateUserRequestDTO
import com.study.alura.challenge.journeymiles.user.dto.response.CreateUserResponseDTO
import com.study.alura.challenge.journeymiles.user.service.UserService
import jakarta.validation.Valid
import org.apache.logging.log4j.LogManager
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/users")
class UserController(private val userService: UserService) {

    private val logger = LogManager.getLogger(this::class.java)

    @PostMapping
    fun create(@RequestBody @Valid createUserRequestDTO: CreateUserRequestDTO): ResponseEntity<CreateUserResponseDTO> {
        return ResponseEntity.ok(
            userService.createUser(createUserRequestDTO).also {
                logger.info("Created a new user with id: ${it.id}")
            }
        )
    }
}
package com.study.alura.challenge.journeymiles.user.dto.request

import jakarta.validation.constraints.Email
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
import java.io.Serializable

data class CreateUserRequestDTO(
    @NotNull(message = "The name field is mandatory")
    @Size(min = 3, max = 100, message = "The name field must bet between 3 and 100 chars")
    val name: String,
    @NotNull(message = "The email field is mandatory")
    @Email
    val email: String,
    @NotNull(message = "The password field is mandatory")
    @Size(min = 6, max = 12, message = "The password field must bet between 6 and 12 chars")
    val password: String
): Serializable

Does anyone has any hints on what's missing?

I have followed almost every tutorial on the internet and still cant find what is wrong with the code

Using bean validation, and triggering validation

UPDATE Sachin's answer worked!


Solution

  • You maybe mixing Java validation with Kotlin's. Try

    data class CreateUserRequestDTO(
        @field:NotNull(message = "The name field is mandatory")
        @field:Size(min = 3, max = 100, message = "The name field must bet between 3 and 100 chars")
        val name: String,
        @field:NotNull(message = "The email field is mandatory")
        @field:Email
        val email: String,
        @field:NotNull(message = "The password field is mandatory")
        @field:Size(min = 6, max = 12, message = "The password field must bet between 6 and 12 chars")
        val password: String
    ): Serializable
    

    You could also check out https://www.baeldung.com/kotlin/valid-spring-annotation