2012-02-24 10 views
6

こんにちは私は以下の機能を持つ単純なDAOを持っています。JPA EntityManager persist()エラーがスローされたにもかかわらずオブジェクトが分離されているように見える

public element createElement(Element e){ 

    em.persist(e); 
    em.flush(); 

    return e; 
} 

エンティティテーブルは、ペア(タイプ、値)の一意性制約を持って、私は次のテストを持っている:

私は「ことを知っているので、私は期待どおり
public void testCreateElement() throws DataAccessException { 
     // Start with empty Element table 

     Element e = new Element(); 
     e.setType(myType.OTHER); 
     e.setValue("1"); 
     dao.createElement(e); 

     e = new Element(); 
     e.setType(MyType.OTHER); 
     e.setValue("1"); 
     try{ 
       // this should violate unique constraint of database. 
       dao.createElement(e); 
     } catch (Exception ex) { 
      System.out.println(ex); 
     } 

     e.setValue("2"); 
     try{ 
      // I expect this to work as there is no element with these values. 
      dao.createElement(e); 
     } catch (Exception ex) { 
      System.out.println(ex); 
     } 
    } 

私の最初のキャッチエラーが発生しました制約に違反メートル、第二のtry/catchは私に関する限り、エラーをスローしてはならないが、それはない、私はそのこの何を得る:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.mypackage.Element 

をだから、(持続呼び出しているようだ)」にたとえ永続化されていなくても休止状態がそれを分離されたエンティティであると考えるようにさせた。

これらの関数は、ConstraintViolation例外を処理しているJSFフロントエンドによって使用されているため、ユーザーがフィールドの1つを変更してやり直すことができるように意図的にオブジェクトを保持し、分離されたエンティティエラー。

これは本当にこれを行う必要があるとは思わないので、この動作は休止状態のバグですか? DAOレベルでこれを回避する方法はありますか?そうでなければ、私のオブジェクトを分離して扱いません。

よろしく、

グレンは、Hibernateによってスローされた例外が回復可能ではありません

+0

あなたは新しい要素を作成し、呼び出し元の最後のcreateElementの前に適切な値を設定するとどうなりますか? –

+0

うまくいく。 – Link19

+0

それは役に立ちますか?そうでなければ、これはうまくいくかもしれません... e.setValue(1); e = dao.createElement(e); (< - 失敗しますが)e.setValue(2); edao.createElement(e); (< - うまくいくでしょう)。 –

答えて

3

をxは。このような例外が発生したときに唯一行うべきことは、トランザクションをロールバックしてセッションを閉じることです。このような例外後のセッション(およびそのエンティティ)の状態は不安定です。

要素のコピーをそのままにしたい場合は、persist()ではなくmerge()を使用するか、要素を複製してから永続化してください。

Hibernateがエンティティを持続してフラッシュするとき、IDを生成してIDをエンティティに割り当ててから、その例外を引き起こす行を挿入することから、例外が予想されることに注意してください。したがって、例外の後、エンティティにはIDが割り当てられているため、Hibernateによって分離されたエンティティと見なされます。あなたはnullにIDをリセットして、それが動作するかどうかを見ることができますが、私は前に、またはマージを使用して、エンティティを複製することをお勧めします。

関連する問題