65

spring-data-rest プロジェクトで Kotlin を 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 文字の名前でユーザーを保存できます。
まったく同じ例を実行する場合にうまく機能しますが、Kotlin ではなく Java クラスで実行します。

これは、Kotlin の問題を考えさせます。

助けてくれてありがとう!

4

2 に答える 2

107

複数のオプションが利用可能な場合、コンストラクターで宣言されたプロパティのデフォルトは、ゲッター(JavaBeans 準拠のホストによって表示される)ではなく、コンストラクターパラメーターのアノテーションをターゲットにするため、アノテーションの use-site ターゲットを使用する必要があります。また、ここでクラスを使用することは不適切な場合があります (末尾の注を参照)。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ターゲットは魅力的に見えるかもしれませんが、Java ではなく Kotlin からのみ確認できます。通常getはトリックを実行し、 bean では必要ありませんset

ドキュメントでは、プロセスを次のように説明しています。

use-site ターゲットを指定しない場合、ターゲットは、使用されているアノテーションの @Target アノテーションに従って選択されます。適用可能なターゲットが複数ある場合は、次のリストの最初の適用可能なターゲットが使用されます。

  • パラメータ
  • 財産
  • 分野

そして、@Size注釈は次のとおりです。

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

したがって、PARAMETERは有効なターゲットであり、複数のターゲット (パラメーター、フィールド、メソッド [get/set]) が利用可能であるため、PARAMETER希望するものではないものを選択します。したがって、JavaBean ホストがプロパティを参照するには、getter を探します (プロパティはバッキング フィールドではなく、getter/setter によって定義されます)。

Java サンプルの 1 つで、次のように表示されます。

public class Book {
    private String title;
    private String description;

    // ...

    @NotEmpty(groups={FirstLevelCheck.class, Default.class})
    @Size(max=30)
    public String getTitle() {
        return title;
    }

    // ...
}

これは、ゲッターで使用するという私たちの使用法と一致します。いくつかの検証注釈が示すようにフィールド上にある場合は、fielduse-site ターゲットを参照してください。または、フィールドもパブリックにアクセスできる必要がある場合は、Kotlin の@JvmField アノテーションを参照してください。

注: 他のユーザーからのメモに記載されているようにdata、エンティティが自動生成 ID を使用する場合は、エンティティにクラスを使用しないことを検討する必要があります。これは、取得されたオブジェクトと同じように新しいオブジェクトには存在しないためです。dataクラスが生成さequalsれ、hashCode含まれるべきではないフィールドを含むすべてのフィールドが含まれます。これに関するガイダンスはHibernate docsから読むことができます。

于 2016-03-07T20:18:44.443 に答える