Пользовательский валидатор компонентов Kotlin, Micronaut и Hibernate никогда не вызывается

#hibernate #kotlin #bean-validation #micronaut #micronaut-data

#спящий режим #kotlin #проверка компонента #micronaut #micronaut-данные

Вопрос:

Я изучаю Micronaut и Kotlin, используя gRPC для проекта на работе, и я столкнулся с некоторыми проблемами, на которые, похоже, не могу найти ответа.

Я пересказываю некоторые личные весенние проекты в Micronaut с использованием Kotlin. В этих проектах я создаю пользовательскую аннотацию валидатора компонента, чтобы проверить, дублируется ли параметр или нет. Я повторил его в Kotlin, но он никогда не вызывался, я также отключил код, и он никогда не останавливается на точках останова в валидаторе.

Вот мой класс сущности, который я хочу проверить. Обратите внимание на аннотацию @uniqueEmail, это мой пользовательский валидатор.

 @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
) {

}
 

Вот класс аннотаций валидатора.

 @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
)
 

А вот и сам валидатор. Вся проблема здесь в том, что Micronaut никогда не вызывает здесь этот метод, значение никогда не проверяется. Другие аннотации bean работают хорошо, например @NotNull и @Email, но не эта.

 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()
    }

}
 

Я много искал, это мой первый вопрос в StackOverflow. Поскольку Micronaut — довольно новый фреймворк, и не так много людей используют Spring / Micronaut с kotlin, очень сложно найти решения ошибок и конкретных проблем, подобных этой.

Заранее признателен за помощь. Спасибо.

Редактировать: Вот мои зависимости:

 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")
}
 

Ответ №1:

UniqueEmailValidator должно быть, фасоль. Это требует @Singleton аннотации.

Комментарии:

1. Спасибо за ответ, но это не сработало. Я добавил @Singleton , больше ничего не изменилось, я также пробовал debbuging, и он никогда не вызывает функцию. Я также пробовал использовать @UniqueEmail and @field:UniqueEmail в своей сущности, и тоже ничего не произошло. Знаете ли вы, есть ли какое-либо другое решение? Как вы думаете, может ли быть какая-то зависимость? Спасибо.

2. Является ли ваше UniqueEmailValidator расширение micronaut ConstraintValidator ?

3. Да, это так. Расширение ConstraintValidator получения моей аннотации UniqueEmail и типа значений String

4. @JimC Мне пришлось отказаться от проекта, потому что вот-вот должен был начаться первый Спринт на моей работе, так что у меня не было много времени, чтобы изучить это. Мне удалось заставить Micronaut получить доступ к аннотации, но по какой-то причине, находясь внутри, он продолжает выполняться в бесконечном цикле, пока компилятор не выдаст a StackOverflowException . У меня есть репозиторий проекта, но я отбросил его некоторое время назад. Вот оно, если вы хотите это проверить , оно находится в сервисах / валидаторах

5. @JimC Многие мои проблемы были связаны с Gradle. Я никогда раньше им не пользовался, привык к Maven. Мне пришлось выработать привычку запускать чистую сборку Gradle каждый раз, когда я что-то менял в коде … иначе какой-нибудь компонент или аннотация перестали бы работать.