kotlin数据类+ bean验证jsr 303

时间:2016-03-07 15:37:34

标签: 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
)

@Size注释在此处无效,使我能够保存名称为1个字符的用户 它在执行相同的示例时效果很好,但在Java类而不是Kotlin中。

这让我想起了Kotlin问题。

先谢谢你的帮助!

2 个答案:

答案 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类会生成equalshashCode以包含所有字段,包括不应包含的字段。您可以从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