2011-07-06 11 views
3

私は自分のアプリケーションのコンテキストで次で有効に休止状態バリデータとの組み合わせで、スプリングベースの検証を使用していますバネを注入したDAOを使用して特定のオブジェクトの有効性制約をチェックします。この結果、java.lang.StackOverflowErrorが発生します。これは、オブジェクトがバリデーター内からデータベースからロードされ、無限ループを引き起こすたびに呼び出されるように見えるためです。これを回避するために、私は次のコードでバリデータ内からコミットするように私のエンティティマネージャでフラッシュモードを設定しようとしている:データベースアクセスは

entityManager.setFlushMode(FlushModeType.COMMIT); 

これは、休止状態からの「コレクションではないプロセスフラッシュによって()」例外が発生します。

カスタムバリデーターからデータベースにアクセスする際のベストプラクティスの例は、これらの問題の両方を回避することができますか?

+0

同様の質問:http://stackoverflow.com/questions/8375704/make-custom-hibernate-validation-annotation-for- email-existence IMHP春の方法は '@ Autowired'サービスやDAOクラスをバリデーターにして、それを通常通り使用することです。 –

答えて

1

多くの実験の後で、これを行う最良の方法は、コード内から直接EntityManagerFactoryを使用することです。バリデータクラスの初期化(...)メソッド私は、次のコードを持って:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu_name"); 
entityManager = emf.createEntityManager(); 

欠点は、あなたがSpringのDI機能を得ることはありませんが、あなたはそれにもかかわらず、データベースにアクセスできることです。私はここに、同様にこの問題に遭遇した

0

が、私はそれを解決する方法である。いくつかの単語で @Autowired bean works with @Valid on controller but fails with CRUD repository

、私はまたEntityManagerFactoryオブジェクトへの参照を得ました。ただし、サービスメソッドを呼び出す直前にsetFlushModeFlushModeType.COMMITに設定しました。最後に、私はFlushModeType.AUTOに戻ってそれを設定します。ここでは

は一例です。

public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> { 

    @PersistenceContext 
    private EntityManager em; 

    @Autowired 
    UserService userService; 

    @Override 
    public void initialize(UniqueUsername constraintAnnotation) {  
    } 

    @Override 
    public boolean isValid(String username, ConstraintValidatorContext context) { 
     try { 
      em.setFlushMode(FlushModeType.COMMIT);   
      return userService.findByUsername(username) == null; 

      } finally { 
      em.setFlushMode(FlushModeType.AUTO); 
      }  
    } 
} 
関連する問題