« Hibernate Shardsをちょっと触る | メイン | Hibernate Searchを触る »

Hibernate Validatorを使う

Hibernate Validatorとは、ドメインモデルに対する制約条件をエンティティクラスにアノテーションで記述することが出来るようにしたHibernateのプロダクトです。エンティティクラスに書くのでバリデーションのコードが重複しにくいことや、アノテーションで手軽にかけるということくらいがウリでしょうか。

Beanのバリデーションを行う仕様は、JSR303 Bean Validationで進められているようです。

  1. 必要なライブラリ
  2. Hibernate Validatorを用いるにはHibernate Core本体、およびCoreが依存するjarに加え、Hibernate Annotationが必要です。
    Core以外には以下のjarがあればよいと思います。

    • ejb3-persistence.jar
    • hibernate-annotations.jar
    • hibernate-commons-annotations.jar
    • hibernate-validator.jar

    最近色々なHibernateのプロダクトがTOPレベルに昇格してきましたが、各プロダクトのバージョンをそろえないとうまく動かなかったりするので注意する必要があります。特にAnnotationは、バージョンが違っていても例外やエラーとなるのではなくアノテーションが適用されずに正常終了というケースもあるので不具合の判別が難しいことがあります。以下はhibernate.orgのCompatibility Matrixの抜粋です。

    Package Version Core Annotations EntityManager Validator Search Shards Tools
    Hibernate Core 3.2.2 GA - 3.2.x, 3.3.x 3.2.x, 3.3.x 3.0.x 3.0.x 3.0.x 3.2.0 Beta9

  3. エンティティクラス
  4. AnnotationとValidatorを使ったエンティティです。すごく簡単です。

    @Entity
    public class Customer implements Serializable {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     public int id;
     @NotNull
     @Length(max = 10)
     public String name;
     @Range(min = 0, max = 100)
     public int age;
     @Email
     public String email;
     @Past
     public Date birthday;
    }

    アノテーションによって上記のエンティティに設定した制約を纏めると以下のような感じです。


    • nameはNULLであってはいけない

    • nameは10文字以内でなければならない

    • ageは0から100の範囲内にある数値でなければならない

    • emailはEメールアドレスの仕様に沿った記述でなければならない

    • birthdayは過去日付でなければならない


    これがアノテーションで書けるのは簡単でいいですね。ビルトインで用意されている制約は他にも@CreditCardNumberとか@Size(コレクションなどのサイズ)などがあります。

  5. 定義ファイル
  6. hibernate.cfg.xmlはこんな感じです。Hibernate Annotation用のmapping定義を追加している程度です。

    <hibernate-configuration>
     <session-factory>
      <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
      <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
      <property name="connection.username">sa</property>
      <property name="connection.password"></property>
      <property name="connection.url">jdbc:hsqldb:hsql://localhost:9001</property>
      <property name="show_sql">true</property>
      <property name="format_sql">true</property>
      <property name="hbm2ddl.auto">create</property>
      <mapping package="net.grandnature.example.entity"/>
      <mapping class="net.grandnature.example.invoice.entity.Customer"/>
     </session-factory>
    </hibernate-configuration>

  7. 動かす
  8. ・・・と言っても普通に動かすだけなのですが

    SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Customer customer = new Customer();
    customer.name = "KIDA Taro";
    customer.age = 76;
    customer.email = "kida@example.com";
    DateFormat parser = DateFormat.getDateInstance();
    ex.birthday = parser.parse("1930/12/06");
    session.save(ex);
    tx.commit();
    session.close();

    このまま動かすと普通に登録されます。もし、例えばbirthdayが未来日付だったりEメールアドレスに不正なものが設定されていたりと、エンティティの状態が制約に違反していると、save時にorg.hibernate.validator.InvalidStateExceptionが投げられます。制約に違反している内容の詳細はInvalidStateExceptionのgetInvalidValuesメソッドで返されるorg.hibernate.validator.InvalidValueの配列に格納されています。

    ただし、@NotNullの制約に引っかかったときはorg.hibernate.PropertyValueExceptionが投げられます。

トラックバック

このエントリーのトラックバックURL:
http://www.grandnature.net/bin/mt-tb.cgi/33

この一覧は、次のエントリーを参照しています: Hibernate Validatorを使う:

» Hibernate Searchを触る 送信元 GrandNature
Hibernate Searchは、アノテーションによってドメインモデルの索引を... [詳しくはこちら]

コメントを投稿

About

2007年04月10日 19:21に投稿されたエントリーのページです。

ひとつ前の投稿は「Hibernate Shardsをちょっと触る」です。

次の投稿は「Hibernate Searchを触る」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。