kotlin 数据 class + bean 验证 jsr 303
kotlin data class + bean validation jsr 303
我正在尝试让 Kotlin 在 spring-data-rest 项目上使用 jsr 303 验证。
给定以下数据 class 声明:
@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 class 而不是 Kotlin 中时运行良好。
这让我想到了一个 Kotlin 问题。
在此先感谢您的帮助!
您需要使用 Annotation use-site targets,因为在构造函数中声明的 属性 的默认值是针对构造函数 参数 上的注释而不是当有多个选项可用时,getter(JavaBeans 兼容主机将看到)。此外,在此处使用 data
class 可能不合适( 请参阅末尾的注释 )。
@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
.
上不需要它
文档将过程描述为:
If you don’t specify a use-site target, the target is chosen according to the @Target annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following list is used:
- param
- property
- field
而 @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。
注意: 正如其他人的注释中提到的,您应该考虑不使用 data
class 对于实体,如果它们使用自动生成的 ID,因为它不会像检索到的对象一样存在于新对象中; data
class 将生成 equals
和 hashCode
以包含所有字段,包括不应该包含的字段。您可以从 Hibernate docs.
中阅读相关指南
为 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
我正在尝试让 Kotlin 在 spring-data-rest 项目上使用 jsr 303 验证。
给定以下数据 class 声明:
@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 class 而不是 Kotlin 中时运行良好。
这让我想到了一个 Kotlin 问题。
在此先感谢您的帮助!
您需要使用 Annotation use-site targets,因为在构造函数中声明的 属性 的默认值是针对构造函数 参数 上的注释而不是当有多个选项可用时,getter(JavaBeans 兼容主机将看到)。此外,在此处使用 data
class 可能不合适( 请参阅末尾的注释 )。
@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
.
文档将过程描述为:
If you don’t specify a use-site target, the target is chosen according to the @Target annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following list is used:
- param
- property
- field
而 @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。
注意: 正如其他人的注释中提到的,您应该考虑不使用 data
class 对于实体,如果它们使用自动生成的 ID,因为它不会像检索到的对象一样存在于新对象中; data
class 将生成 equals
和 hashCode
以包含所有字段,包括不应该包含的字段。您可以从 Hibernate docs.
为 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