2011-03-08 68 views
1

我剛剛設置了一個測試,檢查我能夠使用Hibernate將條目插入到我的數據庫中。讓我瘋狂的事情是Hibernate並沒有真正刪除條目,雖然它報告他們已經不在了!休眠不會刪除我的對象。爲什麼?

下面的測試運行成功,但是當我檢查我的數據庫之後,插入的條目仍然存在!我甚至嘗試使用聲明(是的,我有-ea作爲虛擬機參數)來檢查它。有沒有人有線索爲什麼這些條目不被刪除?

public class HibernateExportStatisticDaoIntegrationTest { 
    HibernateExportStatisticDao dao; 
    Transaction transaction; 

    @Before 
    public void setUp(){ 
     assert numberOfStatisticRowsInDB() == 0; 
     dao = new HibernateExportStatisticDao(HibernateUtil.getSessionFactory()); 
    } 

    @After 
    public void deleteAllEntries(){ 
     assert numberOfStatisticRowsInDB() != 0; 
     Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
     for(PersistableStatisticItem item:allStatisticItemsInDB()) { 
      session.delete(item); 
     } 
     session.flush(); 
     assert numberOfStatisticRowsInDB() == 0; 
    } 

    @Test public void exportAllSavesEntriesToDatabase(){ 
     int expectedNumberOfStatistics = 20; 
     dao.exportAll(StatisticItemFactory.createTestStatistics(expectedNumberOfStatistics)); 

     assertEquals(expectedNumberOfStatistics, numberOfStatisticRowsInDB()); 
    } 

    private int numberOfStatisticRowsInDB() { 
     return allStatisticItemsInDB().size(); 
    } 

    @SuppressWarnings("unchecked") 
    private List<PersistableStatisticItem> allStatisticItemsInDB(){ 
     Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
     transaction = session.beginTransaction(); 
     Query q = session.createQuery("FROM PersistableStatisticItem item"); 
     return q.list(); 
    } 
} 

控制檯充滿

Hibernate: delete from UPTIME_STATISTICS where logDate=? and serviceId=? 

,但是當我檢查什麼已被刪除。

回答

4

我猜這是與交易使用不一致有關(請注意beginTransaction()allStatisticItemsInDB()被多次調用而沒有相應的提交)。

嘗試管理在適當的方式交易,例如,像這樣:

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
Transaction tx = session.beginTransaction(); 
for(PersistableStatisticItem item: 
    session.createQuery("FROM PersistableStatisticItem item").list()) { 
    session.delete(item); 
} 
session.flush(); 
assert session.createQuery("FROM PersistableStatisticItem item").list().size() == 0; 
tx.commit(); 

參見:

+0

你可能是對的,因爲我知道我對Hibernate正確使用的知識接近'nil'。當我明天回去工作並回報時,我會研究這是如何工作的。謝謝! – oligofren 2011-03-08 18:18:12

+0

儘管您提供的代碼不夠完整,但您對事務的原因是正確的。如果使用你的代碼,我會得到一個異常,說當session進入session.delete()時會話被關閉。我不太清楚爲什麼,但我想爲每個邏輯操作(可能包含多個事務)打開一個新會話更有意義。 – oligofren 2011-03-09 10:06:35

+0

還沒有完成那裏... 爲了讓一切工作,這基本上是我所做的。 在涉及查詢數據庫/休眠I: 的每個方法中 - 打開一個新的會話。會話會話= HibernateUtil.getSessionFactory()。openSession(); - 開始了一個新的交易 '會議。beginTransaction();' - 提交交易 'session.flush();' 'session.getTransaction()。commit();' – oligofren 2011-03-09 10:10:36

0

你可以發佈你的DB模式HBM或Fluent地圖?有一件事讓我回想起我在我的Fluent地圖中有一個ReadOnly()。它從未拋出錯誤,我也在日誌中看到了「從blahblah = ...中刪除」的錯誤。

+0

我會在明天檢查上述交易記錄是否成功後再嘗試。謝謝! – oligofren 2011-03-08 18:22:34

+0

似乎這是我開始/結束創建麻煩的交易的sl way方式。不管怎麼說,還是要謝謝你。 – oligofren 2011-03-09 10:11:49

1

我有同樣的問題。儘管我根本沒有使用交易。我用namedQuery這樣的:

Query query = session.getNamedQuery(EmployeeNQ.DELETE_EMPLOYEES); 
int rows = query.executeUpdate(); 
session.close(); 

它返回2行,但數據庫中仍然有所有的記錄。然後我用這個結束上面的代碼:

Transaction transaction = session.beginTransaction(); 
Query query = session.getNamedQuery(EmployeeNQ.DELETE_EMPLOYEES); 
int rows = query.executeUpdate(); 
transaction.commit(); 
session.close(); 

然後它開始工作正常。我正在使用SQL服務器。但我認爲如果我們使用h2,上面的代碼(沒有事務)也可以正常工作。 再一次觀察:插入和獲取記錄事務的使用不是強制性的,但爲了刪除記錄,我們將不得不使用事務。 (只在SQL服務器上測試過)