web-dev-qa-db-ja.com

saveメソッド-例外が発生した後、セッションをフラッシュしません

_public class SoftwareTest extends UnitTest {

    @Before
    public void setup() {
        Fixtures.deleteAll(); // will fail if comment that. why?????
    }

    @Test
    public void createSoftwareWithNullAuthor()  {

       // when author is null

       Author nullAuthor = null;

       Software software = new Software("software1", "description1", nullAuthor);
       try {
         software.save();
         fail("author should not be null");
       } catch (PersistenceException ex) {
       }

    }


    @Test
    public void createSoftwareWithOkAuthor()  {
       // when author is ok
       Author okAuthor = new Author("author1", "email1").save(); // ERROR HERE!

       Software software2 = new Software("software2", "description2", okAuthor);
       Software savedSoftware = software2.save();
       assertNotNull(savedSoftware);
       assertEquals(savedSoftware, software2); 

       assertNotNull(savedSoftware.author);
       assertEquals(okAuthor, savedSoftware.author);
    }
}
_

Fixtures.deleteAll()で行のコメントを解除すると、2番目のメソッドで例外が発生します-createSoftwareWithOkAuthor() when save()作成者。 なぜそれが起こったのですか?

_org.hibernate.AssertionFailure: null id in models.Software entry (don't flush the Session after an exception occurs)
  at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.Java:82)
  at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.Java:190)
  at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.Java:147)
  at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.Java:240)
  at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.Java:99)
  at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.Java:50)
  at org.hibernate.impl.SessionImpl.flush(SessionImpl.Java:1206)
_
13
ses

問題は、Hibernateが例外を発生させる(現在のトランザクションが無効になる)が、そのセッションでさらに多くの操作を続行しようとしていることのようです。

これを行う適切な方法は、使用しているテストを2つに分割し、1つはヌルの作成者をテストし、もう1つは有効な作成者でテストすることです。

本番コード(コントローラーなど)では、続行できるように操作を再開する(トランザクションを閉じ、プロセスを再起動する)必要があります。ただし、playがトランザクションを管理する方法を考えると、通常の動作では、エラーが発生した後、ユーザーにエラーメッセージが返されます。

8
Pere Villega

エラーから:

_org.hibernate.AssertionFailure_:_null id_エントリの_models.Software_(例外が発生した後にSessionをフラッシュしないでください)

以前にセッション例外が発生したことがあるであることがわかります。この_org.hibernate.AssertionFailure_がスローされるポイントは、エラーが発生したポイントではありません。

つまり:何かが元の例外を抑制しています。

したがって、他の考えられるエラーポイントを探してください。 save()またはsaveOrUpdate()は、テーブル内の列が_NOT NULL_であるnullフィールドを持つエンティティを永続化しようとしている可能性があります。

私の場合、real例外は、catchが例外を抑制した_try/catch {}_ブロック内で発生していました(再スローも警告もしませんでした)。

11
acdcjunior

たぶん誰かが私の間違いを繰り返すでしょう:

私もこの問題に遭遇します。私の場合、columnタイプintegerを設定し、long値を書き込もうとしたため、問題が発生しました。 columnタイプを変更すると、動作を開始します。