Issue
I'm studying Micronaut and Kotlin using gRPC for a project at work, and I've ran into some problems that I can't seem to find a answer to.
I'm recriating some personal Spring projects in Micronaut using Kotlin. In those projects I create a custom bean validator annotation to verify if a parameter is duplicated or not. I've recriated it in Kotlin but it's never called, I've also debbuged the code, and it never stops at the breakpoints in the validator.
Here's my Entity class that I want to validate. Note the @UniqueEmail annotation, that's my custom validator.
@Entity
@Validated
@Introspected
@Suppress("unused")
class Autor(
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
val id: String? = null,
@field:NotNull
val instante: LocalDateTime = LocalDateTime.now(),
@field:NotNull
@field:Email
@UniqueEmail(domainClassName = "Autor")
val email: String,
@field:NotNull
val nome: String,
@field:NotNull
@field:Size(max = 400)
val descricao: String
) {
}
Here's the validator annotation class.
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@Constraint(validatedBy = [UniqueEmailValidator::class])
@MustBeDocumented
annotation class UniqueEmail(
val message: String = "Email already exists",
val groups: Array<KClass<Any>> = [],
val payload: Array<KClass<Any>> = [],
val field: String = "email",
val domainClassName: String
)
And here is the validator itself. The whole problem here, is that Micronaut never calls this method here, the value is never validated. The other bean annotations are working well, like @NotNull and @Email, but not this one.
class UniqueEmailValidator(@PersistenceContext val manager: EntityManager) : ConstraintValidator<UniqueEmail, String> {
private lateinit var domainAttribute: String
private lateinit var kClassName: String
override fun initialize(params: UniqueEmail) {
domainAttribute = params.field
kClassName = params.domainClassName
}
override fun isValid(value: String?, context: ConstraintValidatorContext?): Boolean {
if(value.equals("")) return false
val query = manager.createQuery("SELECT e FROM $kClassName WHERE $domainAttribute = :value")
.setParameter("value", value)
return query.resultList.isEmpty()
}
}
I've searched a lot, this is my first question at StackOverflow. As Micronaut is a fairly new framework, and not a lot of people uses Spring/Micronaut with kotlin, this is being a lot difficult to find sollutions to errors and specific problems like this one.
I appreciate in advance for the help. Thanks.
Edit: Here is my dependencies:
dependencies {
kapt("io.micronaut.data:micronaut-data-processor")
implementation("io.micronaut:micronaut-validation")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
implementation("io.micronaut:micronaut-runtime")
implementation("io.micronaut.grpc:micronaut-grpc-runtime")
implementation("javax.annotation:javax.annotation-api")
implementation("io.micronaut.sql:micronaut-jdbc-hikari")
implementation("io.micronaut.sql:micronaut-hibernate-jpa")
implementation("io.micronaut.data:micronaut-data-hibernate-jpa")
implementation("io.micronaut.kafka:micronaut-kafka")
runtimeOnly("org.slf4j:slf4j-simple")
runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin")
runtimeOnly("org.postgresql:postgresql")
testImplementation("io.micronaut:micronaut-http-client")
testRuntimeOnly("org.testcontainers:postgresql")
}
Solution
UniqueEmailValidator
should be a bean. It requires a @Singleton
annotation.
Answered By - Sascha Frinken
Answer Checked By - Mildred Charles (JavaFixing Admin)