您需要使用Annotation use-site targets,因为在构造函数中声明的属性的默认值是针对构造函数parameter上的注释而不是getter(这将当有多个选项可用时,符合 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
)
Kotlin 文档中的 property 目标可能看起来很诱人,但它只能从 Kotlin 而非 Java 中看到。通常get 可以解决问题,而 bean set 不需要它。
文档将过程描述为:
如果不指定使用站点目标,则根据正在使用的注解的@Target 注解选择目标。如果有多个适用目标,则使用以下列表中的第一个适用目标:
而@Size注解是:
@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
因此,由于PARAMETER 是有效目标,并且有多个目标可用(参数、字段、方法 [get/set]),因此它选择了 PARAMETER,这不是您想要的。因此,JavaBean 主机要查看属性,它将查找 getter(属性由 getter/setter 定义,而不是支持字段)。
在Java samples 之一中,它显示:
public class Book {
private String title;
private String description;
// ...
@NotEmpty(groups={FirstLevelCheck.class, Default.class})
@Size(max=30)
public String getTitle() {
return title;
}
// ...
}
这符合我们在 getter 上的用法。如果要像某些验证注释显示的那样在现场,请参阅field 使用站点目标。或者,如果该字段还必须可公开访问,请参阅 Kotlin 中的 @JvmField annotation。
注意: 正如其他人的笔记中提到的,如果实体使用自动生成的 ID,您可能应该考虑不要为实体使用 data 类因为它不会像检索到的对象一样存在于新对象中; data 类将生成 equals 和 hashCode 以包含所有字段,包括不应包含的字段。您可以从Hibernate docs 阅读有关这方面的指导。