jpa - kotlin 数据类 + bean 验证 jsr 303

我正在尝试让 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 问题。

提前感谢您的帮助!

最佳答案

您需要使用 Annotation use-site targets因为当有多个选项可用。在这里也使用 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 上不需要它。

文档将过程描述为:

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 使用站点目标。或者,如果该字段也必须可公开访问,请参阅 @JvmField annotation在 Kotlin 中。

注意: 正如其他人的笔记中提到的,如果实体使用 data 类,您应该考虑不使用它们一个自动生成的 ID,因为它不会像检索到的对象一样存在于新对象中; data 类将生成 equalshashCode 以包含所有字段,包括不应该包含的字段。您可以从 Hibernate docs 阅读有关此内容的指导。 .

https://stackoverflow.com/questions/35847763/

相关文章:

android - JaCoCo 使用 Kotlin 和 Android 3.0 返回 0% 覆盖率

android - Kotlin 单例应用程序类

documentation - 如何在 kotlin kDoc 中使用 @link 和 @code

initialization - 为什么 Kotlin 不允许将 lateinit 与原始类型一起使

android - Kotlin 中的构造函数

java - 如何在 Intellij Idea 12 中重命名/移动项目?

android - java.lang.NoClassDefFoundError $$inlined

android - Kotlin 中的 RecyclerView itemClickListener

kotlin - Kotlin 中的静态方法导入

java - Kotlin 数据类型是基于原始或非原始 Java 数据类型构建的吗?