我试图让Kotlin在spring-data-rest项目中使用jsr 303验证。
给出以下数据类声明:
@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中。
这让我想起了Kotlin问题。
先谢谢你的帮助!
答案 0 :(得分:45)
您需要使用Annotation use-site targets,因为构造函数中声明的属性的默认值是在构造函数参数而不是 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注释选择目标。如果有多个适用目标,则使用以下列表中的第一个适用目标:
- PARAM
- 属性
- 字段
@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;
}
// ...
}
这与我们在吸气剂上使用它的用法相匹配。如果某些验证注释显示在该字段上,请参阅field
使用地点目标。或者,如果该字段也必须可公开访问,请参阅Kotlin中的@JvmField annotation。
注意: 如其他人的说明中所述,如果实体使用自动,您可能会考虑不使用data
类生成的ID,因为对于与检索到的对象相同的新对象,它不存在;并且data
类会生成equals
和hashCode
以包含所有字段,包括不应包含的字段。您可以从Hibernate docs。
答案 1 :(得分:1)
为validation annotations使用@get
或@field
目标。不支持使用目标@param
(第一个默认值)和@property
的注释。
例如:
从@NotEmpty
到@field:NotEmpty
data class Student(
@field:NotEmpty @field:Size(min= 2, message = "Invalid field") var name: String? = ""
)
GL