混乱:JPAおよびHibernateでの@NotNullと@Column(nullable = false)


242
  1. のフィールド/ゲッターに表示される場合、それら@Entityの違いは何ですか?(私はHibernateを通じてエンティティを永続化します)。

  2. それぞれがどのフレームワークや仕様に属していますか?

  3. @NotNull内にありますjavax.validation.constraintsjavax.validation.constraints.NotNulljavadocは言います

    注釈付き要素はnullであってはなりません

    しかし、データベースでの要素の表現については触れていません。なぜnullable=false列に制約を追加するのでしょうか。

回答:


328

@NotNullあるJSR 303ビーン検証アノテーションでは。データベースの制約自体とは関係ありません。ただし、HibernateはJSR 303のリファレンス実装であるため、これらの制約をインテリジェントに取得してデータベースの制約に変換するため、1つの価格で2つ取得できます。@Column(nullable = false)カラムがnullでないことを宣言するJPAの方法です。つまり、前者は検証を目的としており、後者はデータベーススキーマの詳細を示すためのものです。検証アノテーションに関して、Hibernateから追加の(そして歓迎の!)支援を得ているだけです。


2
ありがとう!JPA永続性をHibernate実装に関連付けない(つまり、EJB3に変更する)場合は、両方のアノテーションを使用する必要があります(フィールドとその列の両方でnullを禁止するため)。
2011

3
知りません。JPAプロバイダーがJSR 303アノテーションを認識しなければならないという仕様はありませんが、それは他のプロバイダーが認識しないという意味ではありません。あるかどうかはわかりません。
ライアンスチュワート、

7
JPAプロバイダーは、JSR303実装を提供する必要はありませんが、サードパーティのJSR303実装と統合する機能を提供するために必要な仕様に従っています。したがって、HibernateはJSR303を提供しますが、何らかの理由でそれらを使用せずに他の人と一緒に行くか、openJPAなどのJPA実装を使用してJSR303を提供するために誰かを使用することもできます。また、HibernateのJPA実装もEJB3であることに注意してください。 「私のJPA永続性をHibernate実装に関連付けないようにする場合(つまり、EJB3に変更する場合)」JPAはEJB3仕様の一部です。
Shahzeb 2011

5
@Shahzeb:問題は、誰がJSR 303検証をサポート/提供するかということではありません。それはどのORM(S)のようなJSR 303アノテーションの認識についてです@NotNull@Size@Min@Max、など、データベースの制約にそれらを翻訳します。
ライアンスチュワート

1
はい、しかし私のコメントは、あなたが知らなかったOPがその後のコメントで尋ねたものの文脈で有効です。
Shahzeb 2011

18

休止JPAプロバイダの最新バージョンは、のような豆の検証制約(JSR 303)が適用される@NotNullデフォルト(のおかげでDDLへのhibernate.validator.apply_to_ddl propertyデフォルトtrue)。しかし、他のJPAプロバイダーがそれを行う、またはそれを行う能力さえあるという保証はありません。

@NotNullJVMでJava Beanを検証するときは、Beanのプロパティがnull以外の値に設定されていることを確認するために、Bean検証アノテーションを使用する必要があります(これはデータベースの制約とは関係ありませんが、ほとんどの場合、それらに対応するはずです)。

さらに、JPA @Column(nullable = false)プロバイダーを使用して、JPA プロバイダーに、必要なデータベース制約を持つテーブル列を作成するための適切なDDLを生成するためのヒントを与える必要があります。デフォルトでBean検証制約をDDLに適用するHibernateなどのJPAプロバイダーに依存できる場合、または依存したい場合は、それらを省略できます。


10

興味深いことに、すべてのソースは@Column(nullable = false)がDDL生成にのみ使用されることを強調しています。

ただし、@ NotNullアノテーションがなく、hibernate.check_nullabilityオプションがtrueに設定されている場合でも、Hibernateはエンティティの検証を実行して永続化します。

そのような制限がデータベースレイヤーに実装されていない場合でも、nullable = false属性に値がない場合、「not-nullプロパティはnullまたは一時的な値を参照する」というPropertyValueExceptionをスローします。

hibernate.check_nullabilityオプションの詳細については、http//docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mappingを参照してください。


7

JPA @Columnアノテーション

注釈のnullable属性に@Columnは2つの目的があります。

  • スキーマ生成ツールで使用されます
  • 永続コンテキストのフラッシュ中にHibernateによって使用されます

スキーマ生成ツール

HBM2DDLスキーマ生成ツールは、ステートメントを生成するときに、@Column(nullable = false)エンティティー属性をNOT NULL関連するテーブル列の制約に変換しますCREATE TABLE

私が説明したようにHibernateユーザーガイド、それは次のようなツールを使用することをお勧めしますフライウェイ代わりに、データベーススキーマを生成するためのHBM2DDLメカニズムに依存するので。

永続化コンテキストフラッシュ

永続コンテキストをフラッシュするとき、Hibernate ORMは@Column(nullable = false)エンティティ属性も使用します。

new Nullability( session ).checkNullability( values, persister, true );

検証が失敗した場合、HibernateはをスローしPropertyValueException、INSERTまたはUPDATEステートメントが必要に応じて実行されないようにします。

if ( !nullability[i] && value == null ) {
    //check basic level one nullablilty
    throw new PropertyValueException(
            "not-null property references a null or transient value",
            persister.getEntityName(),
            persister.getPropertyNames()[i]
        );    
}

Hibernateフラッシュメカニズムの動作の詳細については、こちらの記事をご覧ください。

Bean検証@NotNullアノテーション

@NotNull注釈は、HibernateのORMは、最も人気のJPA実装であると同じように、豆の検証によって定義され、最も人気のある豆の検証の実装があるHibernateバリデータフレームワーク。

Hibernate ValidatorをHibernate ORMと共に使用するとConstraintViolation、エンティティの検証時にHibernate Validatorがをスローします。


flywayがスキーマの生成よりも優れていると言うのはなぜですか
Andronicus

1
それは良い観察です。参考リンクで回答を更新しました。
Vlad Mihalcea

参照と素晴らしい回答をありがとう!
Andronicus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.