开发者

save method - doesn't flush the Session after an exception occurs

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;

      开发者_JAVA百科 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);
    }
}

when uncomment the line with Fixtures.deleteAll() we will get en exception in second method - createSoftwareWithOkAuthor() when save() the author. Why that's happened?

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)


From the error:

org.hibernate.AssertionFailure: null id in models.Software entry (don't flush the Session after an exception occurs)

We can see that a session exception has happened before. The point where this org.hibernate.AssertionFailure is thrown is not the point where the error ocurred.

That is: Something is suppressing the original exception.

So look for other possible points of error. A save() or saveOrUpdate() is possibly trying to persist an entity with a null field where, in the table, the column is NOT NULL.

In my case, the real exception was taking place inside a try/catch {} block where the catch suppressed the exception (didn't rethrow or warn me about it).


the issue seems to be that Hibernate raises an exception (so the current transaction gets invalidated) but then you are trying to proceed with more operations in that session.

The proper way to do this would be to split the test you are using in 2, one part to test null authors and one to test with a valid author.

On production code (let's say a controller), you would need to restart the operation (close the transaction, relaunch the process) to be able to proceed. But given the way play manages transactions, the normal behavior would be that after the error you would just return with an error message to the user.


Maybe someone would repeat my mistake:

I also come across with this problem. In my case the problem had occured because I set column type integer, and tried to wrote long value. After changing column type it start to work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜