kotlin数据类+ beanvalidationjsr 303

我试图让Kotlin在spring-data-rest项目中使用jsr 303validation。

给定以下数据类声明:

@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个字符。
当执行完全相同的例子,而不是在Kotlin的Java类中时,它工作的很好。

这使我想到一个Kotlin问题。

在此先感谢您的帮助!

您需要使用Annotation使用站点目标,因为在有多个选项可用时,在构造函数中声明的属性的默认值将定位构造函数参数上的注释,而不是getter (将由JavaBean兼容的主机显示)。

 @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中看到。 通常情况下,这个技巧是不可行的,而且在bean set上是不需要的。

文档描述的过程如下:

如果您未指定使用地点目标,则根据所使用的注释的@Target批注选择目标。 如果有多个适用的目标,则使用以下列表中的第一个适用目标:

  • PARAM
  • 属性
  • 领域

@Size注释是:

 @Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER}) 

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

这与我们在吸气剂上的使用相符。 如果像在某些validation注释中显示的那样在field ,请参阅field use-site target。 或者,如果该字段也必须公开访问,请参阅Kotlin中的@JvmField注释 。

注意: 我没有更改JPA注释,如果有问题,应该检查它们。