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文字の名前でユーザーを保存できます。
これは、Kotlinの代わりにJavaクラスで)まったく同じ例を実行する場合にうまく機能します。
これは私にコトリンの問題を考えさせます。
助けてくれてありがとう!
Annotation use-site targets を使用する必要があります。これは、コンストラクターで宣言されたプロパティのデフォルトが、コンストラクターparameterの代わりにアノテーションを対象とするためですgetter(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
)
Kotlinドキュメントのproperty
ターゲットは魅力的に見えるかもしれませんが、JavaではなくKotlinからのみ見ることができます。通常、get
がトリックを行い、Bean set
では必要ありません。
ドキュメントでは、プロセスを次のように説明しています。
Use-siteターゲットを指定しない場合、ターゲットは、使用されているアノテーションの@Targetアノテーションに従って選択されます。該当するターゲットが複数ある場合、次のリストの最初の該当するターゲットが使用されます。
- param
- 財産
- フィールド
そしてその @Size
注釈は次のとおりです。
@Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})
したがって、PARAMETER
は有効なターゲットであり、複数のターゲット(パラメーター、フィールド、メソッド[get/set])が利用可能であるため、PARAMETER
を選択しますが、これは望みのものではありません。したがって、JavaBeanホストがプロパティを確認するには、ゲッターを探します(プロパティは、バッキングフィールドではなくゲッター/セッターによって定義されます)。
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;
}
// ...
}
これは、getterでの使用法と一致します。検証アノテーションの一部が示すようにフィールド上にある場合は、field
use-siteターゲットを参照してください。または、フィールドもパブリックにアクセスできる必要がある場合は、Kotlinの @ JvmFieldアノテーション を参照してください。
注:他の人からのメモで述べたように、エンティティにdata
クラスを使用しないことを検討する必要があります。取得されたオブジェクトと同じ新しいオブジェクトには存在しないため、自動生成されたIDを使用します。 data
クラスはequals
およびhashCode
を生成し、必要のないフィールドを含むすべてのフィールドを含めます。これに関するガイダンスは Hibernate docs 。から読むことができます。