2011-07-22 56 views
1

在啓用了Spring的集成測試中,我需要強制EntityManager從數據庫重新讀取數據。在集成測試中強制重新加載JPA EntityManager

@Test 
@DataSet("/xml/dbunit/truncate-tables.xml") 
public void createTerminalFromQuery() { 

    // there should be zero terminals in the empty database 
    Assert.assertEquals(0, terminalService.countTerminals()); 

    // makes remote REST call updating database outside the application's EntityManager 
    HttpEntity<QueryResponse> result = simulateRequest("query"); 

    // attempts to force re-read of updated database (unsuccessfully) 
    entityManagerService.getEntityManager().flush(); 

    // there should be exactly one Terminal in the database 
    Assert.assertTrue(terminalService.existsTerminalBySerialNumber(EXISTING_TERMINAL_SERIAL_NUMBER)); 

} 

已經驗證終端已創建並存在於數據庫中。儘管如此,第二個斷言失敗了。當第一個斷言被註釋掉時,第二個斷言是OK的。

測試框架是Unitils/DBUnit,並且通過@PersistenceContext注入一個EntityManager是很困難的,因爲所需的包unitils-orm依賴於Spring 2.5和JPA 1.0導致其他問題。

相反,我創建了EntityManagerService並驗證它確實使用與TerminalService相同的EntityManager。

我已經嘗試EntityManager.clear()和flush()並從EntityManagerFactory驅逐緩存 - 但似乎沒有任何影響。

有什麼建議嗎?

回答

1

您不清楚您如何管理交易。由於clear()沒有幫助,可能兩個檢查都在同一事務內執行,而該事務看不到REST服務提交的事務結果。

嘗試在不同的交易中執行支票。

+0

被叫服務中的事務由Spring處理,但我對事務的理解是非常基本的。 如何確保兩個斷言在不同的事務中執行? 我曾嘗試用@Transactional Propagation.REQUIRES_NEW(絕望地嘗試強制執行/重載/刷新)在自己的私有方法中包裝每個斷言,但那也沒有效果。 – morsor

+0

@morsor:我不太瞭解你的'EntityManagerService'如何與Spring管理的事務交互。如果它手動創建EntityManager,它們可能與Spring託管事務無關,因此您應該通過調用EntityManager的方法手動控制事務。 – axtavt

+0

EntityManagerService使用@PersistenceContext綁定與Terminalservice相同的EntityManager。這兩個服務都是託管的Spring bean。 – morsor