親バカエンジニアのナレッジ帳

webのエンジニアをやっており、日頃の開発で詰まったことや書き残しておきたいことを載せています。

@Columnのlengthやnullableでエラー検知してくれない


Spring Bootのバリデーション

Spring Bootでは、フォームやエンティティクラスにおいて、アノテーションによる入力値チェックが可能なことはご存知でしょう。

一応このブログ内でもフォームのバリデーションについては記しているので参考までに

Spring BootでBean Validation (1) @GroupSequenceで順番にチェック - 親バカエンジニアのナレッジ帳
Spring BootでBean Validation (2) エラーメッセージの多言語化 - 親バカエンジニアのナレッジ帳
Spring BootでBean Validation (3) バリデーション処理を自作 - 親バカエンジニアのナレッジ帳

フォームでの入力値チェック(バリデーション)では、コントローラの処理に移る前に、不正な値を見つけた場合は処理を指定の箇所で中断させてエラー処理に移ることができます。

また、エンティティクラスの入力値チェック(バリデーション)では、データの更新や削除等のDDLが実行される前にエラーを検知することができるので、SQLの実行エラーなど予期せぬエラーを防ぐことができます。

アプリケーションの開発においては両方必要でしょう。



Bean ValidationとJPA定義

フォームとエンティティクラス両方必要ではありますが、フォームのバリデーションではBean Validationが、エンティティクラスのバリデーションではJPA定義をアノテーションで設定します。

Bean Validationの種類としては以下にあります通りですが、

http://itdoc.hitachi.co.jp/manuals/link/cosmi_v0970/03Y2160D/EY210023.HTM

よく使うアノテーションは@Max、@Min、@Size、@NotNull、@Pattern、、、あたりですかね。

JPA定義に関しては、@Columnを付与し、その中で

@Column(length = 30, updatable = false, nullable = false)

等を設定することになります。



Spring Data JPA (Hibernate)使用時のJPA制約

バリデーションチェックでは、正しい形式の値が来ない場合当然エラーを発生させるべきですよね。
ところが、Spring Data JPA (Hibernate)を使用している場合、nullableやlengthの定義に違反している場合でもすり抜けて処理を実行してしまいます。
なので先ほどの、

@Column(length = 30, updatable = false, nullable = false)

においては、エラーで引っかかるのはupdatableのみです。
それだとlengthやnullableは何の意味があるのでしょうか。。。

詳しい原因などは調べてみたのですがよくわかりませんでした。

暫定対応

本来であればBean ValidationとJPA定義はしっかり分けて実装したいところです。
残念ながらそうはいかなくなったので、私は以下のような暫定対応をしました。

@Column(length = 30)
→ @Size(max = 510)に置き換え

@Column(nullable = false)
→ @NotEmptyや@NotNullに置き換え

これが正しいのかはわかりませんが、一応上記に変更するとDDL実行前におかしな値は検知してくれるので。。。


[asin:B078X97MZ9:detail]
[asin:B076LWNZT5:detail]