2011-03-14 55 views
13
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()取消注释该行时,我们将在第二种方法中获得异常 - 当save()为作者时为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) 

回答

8

的问题似乎是,休眠抛出一个例外(因此当前事务都无效),但是你正试图在该届会议上更多的操作进行。

正确的方式做这将是分裂您使用的是2测试,一部分测试空作家,一个具有有效的作者进行测试。

在生产代码(比方说,一个控制器),你就需要重新启动的操作(关闭交易,重新启动的过程),以便能够继续进行。但考虑到播放管理事务的方式,正常的行为将是在错误发生之后,您只会返回错误消息给用户。

+0

是的。这有效,但我也尝试过。但还有另一个问题:在@Before setup()方法中我有Fixtures.deleteAll();如果我评论这条线,那么我会在第二个(分割)方法中出现同样的错误。这里:作者okAuthor = new Author(“author1”,“email1”)。save(); – ses 2011-03-15 08:42:04

+0

我修改了我的问题 – ses 2011-03-15 09:00:51

+0

我们如何阻止会话不会失效? – 2014-03-06 13:23:29

11

从错误:

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

我们可以看到,会话例外以前也发生过。 org.hibernate.AssertionFailure被抛出的地方并不是发生错误的地方。

即:有东西supressing原始异常。

因此,寻找错误的其他可能的点。 A save()saveOrUpdate()可能试图持续存在null字段的实体,其中表中的列为NOT NULL

在我的情况下,真正例外,正在发生一个try/catch {}块内,其中catch supressed除外(不重新抛出或提醒我这件事)。

1

也许有人会重复我的错误:

我也有这个问题碰到过。在我的情况下,问题发生,因为我设置column类型integer,并试图写long值。在更改column类型后,它开始工作。