Bean Validationで@Unique
制約を使用したいのですが、標準では提供されていません。 JPAの@UniqueConstraint
を使用する場合、独自の検証およびエラー報告メカニズムはありません。
@Unique
をBean Validation制約として定義し、JPAと組み合わせて、JPAが一意の制約を持つ列を作成し、値が一意かどうかをチェックする方法はありますか?
テーブル全体のロックを取得しない限り、基本的にSQLクエリを使用してユニシティをチェックすることはできません(同時トランザクションは手動でチェックしますが、進行中のトランザクションのコミット前に)。つまり、Javaレベルで有効な一意の検証を実装することはできず、検証実装を提供することはできません。単一性を確認する唯一の信頼できる方法は、トランザクションをコミットすることです。
BV仕様は次のように要約しています。
付録D. Java Persistence 2.0統合
質問:@Column(unique = true)にマップする@Uniqueを追加する必要がありますか?
@Uniqueは、Javaレベルで確実にテストすることはできませんが、データベースの一意制約生成を生成できます。@ Uniqueは、現在のBV仕様の一部ではありません。
したがって、Bean Validation例外でラップされた一意の(およびnull以外の)制約違反があるといいことに同意しますが、現在はそうではありません。
@Uniqueの実装方法とその周辺の問題に関する詳細は、ここにあります- http://community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator
さて、あなたはそれを行うことができますが、それは簡単ではありません。問題は、挿入する値が既に存在するかどうかを確認するために、バリデーターがいくつかのクエリを実行するためにデータベースアクセスを必要とすることです。そして、これは実際にはバリデーターからは行えません。sessionFactory/ sessionにアクセスできないからです。もちろん、バリデーター内でインスタンス化することができます(session/sessionFactory)が、それは良いコーディング手法ではありません。
バリデーターに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;
...
}