kotlin数据类+ bean验证jsr 303

pel*_*ger 36 jpa bean-validation kotlin spring-data-rest data-class

我试图让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
)
Run Code Online (Sandbox Code Playgroud)

@Size注释在这里没有任何效果,使我能够保存名称为1个字符的用户.
它在执行相同的示例时效果很好,但在Java类而不是Kotlin中.

这让我想起了Kotlin问题.

在此先感谢您的帮助!

Jay*_*ard 61

您需要使用Annotation使用站点目标,因为构造函数中声明的属性的默认值是在有多个可用选项时,在构造函数参数而不是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
)
Run Code Online (Sandbox Code Playgroud)

property来自Kotlin文档的目标可能看起来很诱人,但它只能从Kotlin而不是Java中看到.通常可以get做到这一点,并且bean上不需要它set.

文档将过程描述为:

如果未指定use-site目标,则根据正在使用的注释的@Target注释选择目标.如果有多个适用目标,则使用以下列表中的第一个适用目标:

  • PARAM
  • 属性
  • 领域

@Size注释是:

@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
Run Code Online (Sandbox Code Playgroud)

因此,因为它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;
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

这符合我们在getter上使用它的用法.如果某些验证注释显示在该字段上,请参阅fielduse-site目标.或者,如果该字段也必须可公开访问,请参阅Kotlin中的@JvmField注释.

注意: 如其他人的说明中所述,data如果实体使用自动生成的ID ,则应考虑不使用实体类,因为对于与检索到的对象相同的新对象,它不存在; 并且一个data类将生成equalshashCode包括所有字段,包括它不应该的字段.您可以从Hibernate文档中阅读有关此内容的指导.

  • 虽然这是正确的答案,但值得注意的是,你不应该为实体使用`data class`.原因是 - 它将使用所有属性生成`equals`和`hashCode`方法,包括`id`,这对于JPA实体来说不是理想的行为.请参阅:https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/persistent-classes-equalshashcode.html (3认同)
  • “如果在数据类主体或超类中的最终实现中有 equals()、hashCode() 或 toString() 的显式实现,则不会生成这些函数,并使用现有实现”- kotlin 文档 (2认同)

COR*_*ian 8

使用@get@field目标进行验证注释。不支持带有目标的注释@param(第一个默认值)@property

例如:

@NotEmpty@field:NotEmpty

data class Student(
    @field:NotEmpty @field:Size(min= 2, message = "Invalid field") var name: String? = ""
)
Run Code Online (Sandbox Code Playgroud)

GL