2010-04-20 49 views
1

我想測試Hibernate映射,特別是一個獨特的約束。我的POJO映射如下:如何在休眠狀態下正確測試約束違規?

<property name="name" type="string" unique="true" not-null="true" /> 

我想要做的是測試我不能堅持兩個實體具有相同的名稱:

public class ExpertiseAreaDAOTest{ 
    private ExpertiseAreaDAO ead; 
    static Connection c; 
    private static SessionFactory sessionFactory; 

    static { 
     Configuration config = new Configuration().configure("resources/exp/hibernate-test.cfg.xml"); 
     sessionFactory = config.buildSessionFactory(); 
    } 

    @Test(expected=ConstraintViolationException.class) 
    public void testPersistTwoExpertiseAreasWithTheSameNameIsNotAllowed(){ 
     ExpertiseArea ea = new ExpertiseArea("Design"); 
     ExpertiseArea otherEA = new ExpertiseArea("Design"); 

     ead.setSession(getSessionFactory().getCurrentSession()); 
     ead.getSession().beginTransaction(); 
     ead.makePersistent(ea); 
     ead.makePersistent(otherEA); 
     ead.getSession().getTransaction().commit(); 
    } 

    public static SessionFactory getSessionFactory(){ 
     return sessionFactory; 
    } 
} 
//Other methods ommited 

在commiting當前事務,我可以看到一個ConstraintViolationException拋出日誌:

16:08:47,571 DEBUG SQL:111 - insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?) 
Hibernate: insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?) 
16:08:47,571 DEBUG SQL:111 - insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?) 
Hibernate: insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?) 
16:08:47,572 WARN JDBCExceptionReporter:100 - SQL Error: -104, SQLState: 23505 
16:08:47,572 ERROR JDBCExceptionReporter:101 - integrity constraint violation: unique constraint or index violation; SYS_CT_10036 table: EXPERTISEAREA 
16:08:47,573 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 

所以我希望測試通過,因爲預期ConstraintViolationException被拋出。然而,測試永遠不會完成(既不通過也不失敗),我不得不手動殺死測試跑步者。

什麼是測試這個的正確方法?

回答

2

不應該在兩個事務中運行創建,期望第一個成功,第二個失敗?

public void testPersistTwoExpertiseAreasWithTheSameNameIsNotAllowed(){ 
    ExpertiseArea ea = new ExpertiseArea("Design"); 
    ExpertiseArea otherEA = new ExpertiseArea("Design"); 

    SessionFactory sf = getSessionFactory(); 
    Session session = sf.openSession(); 
    Transaction txn = session.beginTransaction(); 
    try { 
     ead.setSession(session); 
     ead.makePersistent(ea); 
     // no ExpertiseArea by this name in DB, this should commit 
     txn.commit(); 
    } catch (HibernateException ex) { 
     txn.rollback(); 
     fail("Unexpected exception " + ex); 
    } finally { 
     session.close(); 
     ead.setSession(null); 
    } 
    session = sf.openSession(); 
    txn = session.beginTransaction(); 
    try { 
     ead.setSession(session); 
     ead.makePersistent(otherEA); 
     // this should fail 'cos there is already an ExpertiseArea with 
     // the same name in DB 
     txn.commit(); 
     fail("Expected constraint violation exception"); 
    } finally { 
     session.close(); 
     ead.setSession(null); 
    } 
} 
+0

我試過了,但得到完全一樣的結果。 – Cesar 2010-04-20 23:35:22

+0

您是否嘗試過在測試中手動創建'Session'? – 2010-04-20 23:56:17

+0

是的,實際上會話是在測試中內部創建的。或者,您是通過手動創建會話意味着什麼?我編輯了我的問題來反映這一點。 – Cesar 2010-04-21 00:05:08