2011-07-26 86 views
2

我在測試DAOObject時遇到問題。我有兩個通過@oneToOne關係鏈接的實體。 這些類是:Spring,Hibernate @OneToOne交易測試問題

@Entity 
@Table 
public class Device extends HyEntity { 

    @OneToOne(mappedBy = "device") 
    private EndUser endUser; 
    //getters+setters 
} 

@Entity 
@Table 
public class EndUser extends HyEntity { 

    private String firstname; 
    private String lastname; 
    @OneToOne 
    private Device device; 
    //getters+setters 
} 

在DAO我做到以下幾點:

Device d1 = new Device(); 

    EndUser e1 = new EndUser(); 
    e1.setFirstname("Hans"); 
    e1.setLastname("Muster"); 
    e1.setDevice(d1); 

    repo.saveEntity(d1); 
    repo.saveEntity(e1); 
    sf.getCurrentSession().flush(); 
    repo.updateEntity(d1); 
    sf.getCurrentSession().flush(); 

    Assert.notNull(repo.getEndUserById(e1.getId())); 
    Assert.notNull(repo.getEndUserById(e1.getId()).getDevice()); 
    Assert.notNull(repo.getDeviceById(d1.getId())); 

    sf.getCurrentSession().flush(); 
    d1 = repo.getDeviceById(d1.getId()); 
    Hibernate.initialize(d1); 
    Hibernate.initialize(d1.getEndUser()); 
    Assert.notNull(repo.getDeviceById(d1.getId()).getEndUser()); //FAILS endUser of Device is always NULL 

正如你所看到的,既不調用Session.flush(),也不Hibernate.Initalize作品。最終用戶不是設備的設備。 如果我刪除了@Transactional,那麼......一切正常。 有沒有辦法讓這個工作? 否則,我將永遠不得不在測試後手動刪除數據庫中創建的實體,這非常煩人。

希望能回答。

在此先感謝。

+0

也許'd1.setEndUser(e1)'有幫助嗎? – marc

+1

這會幫助我猜。我認爲事情就是它在非事務性測試中按照預期工作,但不在事務性測試中工作。 – chzbrgla

+1

是的,如果我添加了'd1.setEndUser(e1);'但是這只是一個解決方法...我認爲應該有可能得到這個工作沒有這樣的解決方法。沒有@transactional它正在工作... – drame

回答

1

您需要在上次刷新後添加clear()。如果你錯過了這一點,那麼hibernate將會從其內部緩存中完全返回SAME實例,其中的更新不會被更新。

無論如何,我個人認爲這是不好的做法,不要手動設置雙方的關係。 - 因爲如果你沒有將它設置在雙方,你總是必須小心從數據庫重新加載實體。如果你不從數據庫重新加載實體比...(參見你的測試)。

+0

非常感謝。清除()完成了這個訣竅。 我注意到有某種緩存,但我沒有發現它在會話中,並且clear()會清除它。 ^^ – drame