2016-03-07 149 views
15

我试图让Kotlin在spring-data-rest项目上使用jsr 303验证。kotlin数据类+ bean验证jsr 303

给出下面的数据类declarartion:

@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

注解的目标应该是什么?构造函数参数还是字段? – voddan

回答

23

您需要使用Annotation use-site targets因为默认的构造函数声明的属性是针对在构造函数中的注释参数代替吸气(将由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 
) 

从科特林文档的property目标可能看起来很诱人,但它只能从科特林而不是Java见过。通常get会诀窍,并且它在豆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阅读关于这方面的指导。

+0

你摇滚!谢谢 ! 也可以使用'@get:Size(min = 5,max = 15)'注释。 – pellenberger

+2

虽然它是正确的答案,但值得注意的是,不管怎样都不应该为实体使用'data class'。原因是 - 它将使用所有属性生成equals和hashCode方法,包括'id',这对JPA实体来说不是理想的行为。看到这里:https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/persistent-classes-equalshashcode.html – waste

+0

谢谢@waste,我做了一个编辑,直接添加注释在回答。 –