2016-03-07 122 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,我做了一個編輯,直接添加註釋在回答。 –