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()我们将在第二种方法中获得en异常- createSoftwareWithOkAuthor() 当save()作者。 为什么会这样呢?
Fixtures.deleteAll()
createSoftwareWithOkAuthor()
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)
问题似乎是Hibernate引发了一个异常(因此当前事务无效),但是随后您尝试在该会话中继续执行更多操作。
正确的方法是将您使用的测试分为2部分,一部分测试空作者,另一部分测试有效作者。
在生产代码(例如控制器)上,您需要重新启动操作(关闭事务,重新启动流程)才能继续。但是,考虑到游戏管理交易的方式,通常的行为是在发生错误之后,您只会向用户返回错误消息。