2016-03-07 17 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文字の名前でユーザーを保存することができ、私はなって、ここには効果がありません。
これは、まったく同じ例を実行してもKotlinではなくJavaクラスでうまく動作します。

これは私にコトリン問題を考える。

ご協力いただきありがとうございます!

+0

注釈の対象は何ですか?コンストラクタパラメータまたはフィールド? – voddan

答えて

23

複数がある場合、コンストラクタで宣言されたプロパティのデフォルトはコンストラクタパラメータの代わりに、(JavaBeansの対応のホストが見られます)ゲッターに注釈を標的とすることであるので、あなたは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がトリックを行い、それは豆の上には必要ありませんset

ドキュメントのようにプロセスを説明します。あなたは利用サイトのターゲットを指定しない場合

、ターゲットが使用されている注釈の@Target注釈に従って選択されます。

  • のparam
  • プロパティ
  • フィールド

そして@Size注釈は次のとおりです:複数の適用対象がある場合は、以下のリストからの最初の適用対象が使用され

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

したがって、PARAMETERは有効なターゲットであり、複数のターゲットが利用可能です(パラメータ、フィールド、メソッド[取得/設定])。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を参照してください。

注:他人からノートに述べたように、それは新しいオブジェクトのために取得した場合と同じに存在しないので、彼らが自動生成されたIDを使用している場合、あなたはおそらくエンティティのdataクラスを使用していない検討すべきですオブジェクト; dataクラスは、equalshashCodeを生成し、含まないフィールドをすべて含むようにします。 Hibernate docsからこれに関するガイダンスを読むことができます。

+0

ロック!ありがとう! '@get:Size(min = 5、max = 15)'アノテーションを使うこともできます。 – pellenberger

+2

それは正解ですが、とにかくエンティティに 'data class'を使うべきではないことに注意する価値があります。その理由は、 'id'を含むすべてのプロパティを使用して' equals'メソッドと 'hashCode'メソッドを生成します。これはJPAエンティティにとって望ましい動作ではありません。こちらをご覧ください:https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/persistent-classes-equalshashcode.html – waste

+0

ありがとうございました@waste、私はノートを直接回答。 –

関連する問題