2012-05-15 61 views
1

這應該是一件輕而易舉的事情,但我無法讓它工作。如何恢復對Hibernate中實體擁有的集合的更改?

我希望能夠將掛在實體(我們稱之爲貓)上的延遲集合(讓我們稱之爲小貓)的變化恢復到一個Hibernate會話中維護的集合。

收集被定義爲這樣(與貓和小貓更換我平淡的實體):

@Entity 
@Table(name="CAT") 
public class Cat { 

    private Map<Long, Kitten> kittens; 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="mother", cascade={CascadeType.ALL}) 
    @MapKey(name="id") 
    public Map<Long, Kitten> getKittens() { 
     return kittens; 
    } 

    ... 
} 

@Entity 
@Table(name="KITTEN") 
public class Kitten { 

    private Cat mother; 

    @ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CadcadeType.MERGE) 
    @JoinColumn(name="MOTHER_CAT_ID", nullable=false) 
    public Cat getMother { 
     return mother; 
    } 

    ... 
} 

用戶可以添加並從小貓收集到他們的心臟的內容刪除而不會被明確地堅持,直到他們保存並執行會話刷新。

但是,如果用戶選擇恢復小貓的原始列表,應該再次從數據庫中檢索。

我試圖通過從二級緩存逐出小貓集合,實現集合的這個充滿逆轉,然後重新得到使用以下方式從數據庫中貓實體:

public class CatDao { 

    public Cat reset(Cat cat) { 

     SessionFactory sessionFactory = Util.getSessionFactory(); 
     sessionFactory.evictCollection(Cat.class.getName() + ".kittens", cat.getId()); 

     Cat original = (Cat)this.session.get(Cat.class, cat.getId()); 
     Hibernate.initialize(original.getKittens()); 

     return original; 
    } 

    ... 
} 

它不會從數據庫中重新檢索小貓(如日誌所示)。我究竟做錯了什麼?

回答

3

只要它們仍在第一級高速緩存中,從第二級高速緩存中逐出小貓就沒有效果。這是對象從哪裏加載的地方。而在第一級緩存中只有引用,即i。即當您修改實例並從第一級緩存重新加載實體時,您將再次獲得修改後的實例。

第一級緩存位於會話對象內部。你必須使用Session.evict()從會議中驅逐小貓。 (Session.clear()或創建新的會話具有相同的效果,但會強制重新加載存儲在會話第一級緩存中的所有對象,這取決於您的應用程序,如果這是更好的解決方案)。我想,你不需要隨時撥打SessionFactory.evictCollection()。順便說一句,SessionFactory.evictCollection()被標記爲已棄用。

+0

謝謝@Johanna。你在這兩方面都是正確的。 – Lisa

相關問題