2011-03-14 54 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類型後,它開始工作。