Класс данных kotlin + bean проверка jsr 303

Я пытаюсь заставить Kotlin работать с проверкой jsr 303 в проекте spring -data-rest.

Учитывая следующее объявление класса данных:

@Entity data class User(
    @Id 
    @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
    var id: Long? = null,

    @Size(min=5, max=15)
    val name: String
)

Аннотация @Size не имеет никакого эффекта здесь, что позволяет мне сохранять пользователя с именем 1 символ.
Он отлично работает при выполнении того же примера, но в классе Java вместо Kotlin.

Это заставляет меня думать о проблеме Котлина.

Заранее благодарим за помощь!

Ответы

Ответ 1

Вам нужно использовать цели использования целевого объекта аннотации, поскольку значение по умолчанию для свойства, объявленного в конструкторе, предназначено для таргетинга аннотации на параметр конструктора вместо getter (который будет отображаться хостами, совместимыми с JavaBeans), когда доступно несколько опций.

@Entity data class User(
    @Id
    @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
    var id: Long? = null,

    @get:Size(min=5, max=15) // added annotation use-site target here
    val name: String
)

Цель property из документов Kotlin может показаться соблазнительной, но ее можно увидеть только из Kotlin, а не из Java. Обычно get выполняет трюк, и он не нужен на bean set.

Документы описывают процесс как:

Если вы не указали цель использования сайта, цель выбирается в соответствии с аннотацией @Target используемой аннотации. Если имеется несколько применимых целей, используется первая применимая цель из следующего списка:

  • пары
  • свойство
  • поле

И аннотация @Size:

@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})

Следовательно, поскольку PARAMETER является допустимой мишенью, и доступны несколько целей (параметр, поле, метод [get/set]), он выбирает PARAMETER, который не является тем, что вы хотите. Поэтому для хоста JavaBean, чтобы увидеть свойство, он будет искать getter (свойства определяются с помощью getter/setter, а не поля поддержки).

В одном из примеров Java он показывает:

public class Book {
    private String title;
    private String description;

    // ...

    @NotEmpty(groups={FirstLevelCheck.class, Default.class})
    @Size(max=30)
    public String getTitle() {
        return title;
    }

    // ...
}

Что соответствует нашему использованию его на геттере. Если бы это было на поле, как показывают некоторые аннотации проверки, см. Цель field use-site. Или, если поле также должно быть общедоступным, см. @JvmField аннотация в Kotlin.

ПРИМЕЧАНИЕ. Я не изменял аннотации JPA, вы должны проверить их, если у вас есть проблемы.