2014-11-05 93 views
0

我的模型看起來像這樣(在現實情況下,有getter和setter):合併分離對象刪除兒童

class Foo { 
    Set<Bar> bars; 

    void attachBars(Set<Bar> bars){ 
     this.bars = bars; 
     for(Bar bar : bars) 
      bar.foo = this; 
    } 
} 
class Bar { 
    Set<Baz> bazes; 
} 
class Baz { 
} 

然後我執行:

Foo foo = e.find(Foo.class, "id"); 
Hibernate.initialize(foo.bars); 
em.detach(foo) 

Foo foo2 = e.find(Foo.class, "id"); 
doSomeChanges(foo2); 
foo2.attachBars(foo.bars); 

我看到的在調試器:

之前attachBars(foo.bars);bar.bazes字段不可訪問由於LazyInitializationException

之後attachBars(foo.bars);其中bar.bazes字段設置爲空,並且在em.merge之後,將bazes從數據庫中刪除。

回答

0

attachBars方法不應該改變對this.bar的引用。它會/由Hibernate實例化,因爲我們通過find()(即Hibernate會話)檢索了foo。參考這個集合是必不可少的,監守只有這樣,我們可以依靠適當的髒檢查(新增,刪除的項目)

因此,它應該是這樣的(預期收集是由Hibernate實例化)

void attachBars(Set<Bar> bars){ 
    if(this.bars == null){ 
     this.bars = new HashSet<Bar>(); 
    } 
    for(Bar bar : bars){ 
     this.bars.add(bar); 
     bar.foo = this; 
    } 
} 

但是在這種情況下,這並不是必須的。傳遞的集合bars來自分離的對象。根本沒有填充bazes集合。

將它們重新添加到剛加載的對象後,它們似乎有空集合。所以在我們拆除根對象之前,我們也應該強制所有Baz實例初始化。

更好的解決方案,我建議是由ID迭代老筋收集和負載的實際代理

+0

帶附加bars.clear(),但確定。我會檢查這是否是問題。 – Krever 2014-11-05 14:08:21