2014-11-05 94 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