web-dev-qa-db-ja.com

JPAおよびBean Validationを使用した一意の制約

Bean Validationで@Unique制約を使用したいのですが、標準では提供されていません。 JPAの@UniqueConstraintを使用する場合、独自の検証およびエラー報告メカニズムはありません。

@UniqueをBean Validation制約として定義し、JPAと組み合わせて、JPAが一意の制約を持つ列を作成し、値が一意かどうかをチェックする方法はありますか?

37
deamon

テーブル全体のロックを取得しない限り、基本的にSQLクエリを使用してユニシティをチェックすることはできません(同時トランザクションは手動でチェックしますが、進行中のトランザクションのコミット前に)。つまり、Javaレベルで有効な一意の検証を実装することはできず、検証実装を提供することはできません。単一性を確認する唯一の信頼できる方法は、トランザクションをコミットすることです。

BV仕様は次のように要約しています。

付録D. Java Persistence 2.0統合

質問:@Column(unique = true)にマップする@Uniqueを追加する必要がありますか?

@Uniqueは、Javaレベルで確実にテストすることはできませんが、データベースの一意制約生成を生成できます。@ Uniqueは、現在のBV仕様の一部ではありません。

したがって、Bean Validation例外でラップされた一意の(およびnull以外の)制約違反があるといいことに同意しますが、現在はそうではありません。

参照資料

50
Pascal Thivent

@Uniqueの実装方法とその周辺の問題に関する詳細は、ここにあります- http://community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator

5
Hardy

さて、あなたはそれを行うことができますが、それは簡単ではありません。問題は、挿入する値が既に存在するかどうかを確認するために、バリデーターがいくつかのクエリを実行するためにデータベースアクセスを必要とすることです。そして、これは実際にはバリデーターからは行えません。sessionFactory/ sessionにアクセスできないからです。もちろん、バリデーター内でインスタンス化することができます(session/sessionFactory)が、それは良いコーディング手法ではありません。

3
Mateusz Dymczyk

バリデーターにJPAアノテーションを読み取らせて適用できます。以下は、拡張するアイデアとして使用できるスプリングバリデータを使用した例です。

JPA JSR303 Spring Form Validation

@InjectまたはSpringの@Autowired)カスタムバリデータのセッションBeanとコンテナは、それを接続する方法を知っている必要があります。私はこれをSpringの例としてのみ知っています:

import javax.validation.ConstraintValidator;

public class MyConstraintValidator implements ConstraintValidator {

@Autowired //@Inject
private Foo aDependency;

...
}
2
dukethrash