2011-06-23 80 views
0

我有以下2週休眠的entites:Hibernate的集合緩存問題

@Entity 
@Table(name = "VEHICLE_BRAND") 
public class VehicleBrand implements java.io.Serializable { 

    ... 

    @Column(name = "NAME", nullable = false, length = 1000) 
    public String getName() { 
    return name; 
    } 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "vehiclebrand") 
    public Set<VehicleModel> getVehicleModels() { 
    return vehicleModels; 
    } 

    ... 

} 

@Entity 
@Table(name = "VEHICLE_MODEL") 
public class VehicleModel implements java.io.Serializable { 

    ... 

    @Column(name = "NAME", nullable = false, length = 1000) 
    public String getName() { 
    return name; 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="VECHILE_BRAND_ID") 
    public VehicleBrand getVehicleBrand() { 
    return this.vehicleBrand; 
    } 

    ... 

} 

而且我有哪些測試VehicleBrand和VehicleModel以下的單元測試:

DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(); 
txDef.setName("test1"); 
txDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
TransactionStatus txStatus = txManager.getTransaction(txDef); 

// Load brand "1" object. 
VehicleBrand brand = (VehicleBrand) factory.getVehicleBrandDAO().findFirstByName("1"); 
assertNotNull(brand); 

// Check if model "X" exists for brand "1" through collection. 
Set<VehicleModel> models = brand.getVehicleModels(); 
for (final VehicleModel model : models) { 
    assertFalse(model.getName().equals("X")); 
} 

// Add model "X" to brand "1". 
VehicleModel model = new VehicleModel(); 
model.setName("X"); 
model.setValidFrom(new Date()); 
model.setVehicleBrand(brand); 
factory.getVehicleModelDAO().create(model); 

txManager.commit(txStatus); 

txDef = new DefaultTransactionDefinition(); 
txDef.setName("test2"); 
txDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
txStatus = txManager.getTransaction(txDef); 

// Check that model is added to database. 
model = (VehicleModel) factory.getVehicleModelDAO().findFirstByName("X"); 
assertNotNull(model); 
assertEquals(model.getVehicleBrandId().longValue(), 1L); 

// Check if model X exists for brand "1" through collection. 
brand = (VehicleBrand) factory.getVehicleBrandDAO().findFirstByName("1"); 
models = brand.getVehicleModels(); 
boolean found = false; 
for (final VehicleModel model2 : models) { 
    if (model2.getName().equals("X")) { 
    found = true; 
    } 
} 
assertTrue(found); 

txManager.commit(txStatus); 

有人能解釋我爲什麼最後一行失敗嗎?

+0

你可以使用'getNavn'的片段或將存儲在數據庫中的關聯成員更新代碼嗎? –

+0

對不起,這是一個錯字,它被稱爲getName,並且我已經在問題中爲實體添加了getter/annotation定義 –

+0

我已更新測試用例以確保在請求之間啓動新的事務 –

回答

1

它肯定會失敗,因爲您在同一事務中執行所有這些操作,因此始終會從會話緩存中返回相同的VehicleBrand實例。

由於您在創建您的VehicleModel時(即您將品牌分配給新模型,但忘記將創建的模型添加到品牌的模型集合),您忘記保持關聯的兩側,同一組模型總是返回,並且不包含新創建的模型。

+0

1)查找請求在不同的hibernate會話中執行,2)我還可以從日誌中看到,在每個findFirstByName中有一個針對數據庫執行的SQL查詢 –

+0

您是否檢查過模型是的確在第一筆交易的末尾寫入數據庫,並且其名稱和品牌ID是正確的(因爲交易已提交,您應該能夠在數據庫中看到它)? –