Класс данных Kotlin + проверка бинов JSR 303
Я пытаюсь заставить Котлина работать с проверкой 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 ответ
Необходимо использовать цели сайта аннотации, поскольку по умолчанию для свойства, объявленного в конструкторе, указывается аннотация на параметре конструктора вместо метода получения (который будет виден хостам, совместимым с JavaBeans), когда доступно несколько опций. Также используя data
класс может быть неуместным здесь (см. примечание в конце).
@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
делает трюк, и это не нужно на боб set
,
Документы описывают процесс как:
Если вы не укажете цель сайта использования, цель будет выбрана в соответствии с аннотацией @Target используемой аннотации. Если имеется несколько применимых целей, используется первая применимая цель из следующего списка:
- пары
- имущество
- поле
И @Size
аннотация это:
@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
Поэтому с PARAMETER
является допустимой целью, и доступно несколько целей (параметр, поле, метод [get/set]), которые он выбирает PARAMETER
что не то, что вы хотите. Поэтому, чтобы узел JavaBean видел свойство, он будет искать получателя (свойства определяются получателем / установщиком, а не полем поддержки).
В одном из примеров 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
цель использования сайта. Или, если поле также должно быть общедоступным, см. Аннотацию @JvmField в Kotlin.
ПРИМЕЧАНИЕ. Как уже упоминалось в комментариях других, вы, вероятно, должны рассмотреть НЕ использовать data
класс для сущностей, если они используют автоматически сгенерированный идентификатор, поскольку он не будет существовать для новых объектов так же, как для извлеченных объектов; и data
класс будет генерировать equals
а также hashCode
включить все поля, включая те, которые не должны. Вы можете прочитать руководство по этому вопросу из документов Hibernate.
Использовать @get
или @field
цели для проверочных аннотаций. Аннотации с целью@param
(первое значение по умолчанию) и @property
не поддерживаются.
например:
От @NotEmpty
Чтобы @field:NotEmpty
data class Student(
@field:NotEmpty @field:Size(min= 2, message = "Invalid field") var name: String? = ""
)
GL