2012-07-22 45 views
2

休眠的EntityManager 3.4.0或3.6.10休眠/ JPA:em.merge没有集合(新myEntity所(ID))返回代理

MyEntity { 
    @Id // NOT @GeneratedValue 
    long cislo; 

    @OneToMany(...) 
    List<MyItem> items = new ArrayList(); 


    public MyEntity(long cislo) { this.cislo = cislo; } 
    ... 
} 

,然后在一个DAO:

MyEntity ent = new MyEntity(id); 
ent.addItem(new Item(...)); 
ent.addItem(new Item(...)); 
ent = em.merge(ent); 

1)为什么我需要使用merge()而不是persist()哪个会抱怨实体被分离?是否需要手动设置ID?

2)为什么这个合并返回一个没有收藏集的代理?

3)最重要:如何从merge()获得完全初始化的实体?
除了设置EAGER上的成员colections。
我可以使用原始对象,但我很好奇它是否可能。 我可以查询实体,但这似乎是浪费资源。

回答

0

1.)为什么在这里使用“Session.merge()”?合并通常用于将分离的实体实例重新附加到Hibernate/JPA会话 - 这通常会在会话外重用实体实例(例如,在视图图层中)并且您想要将这些实例的任何更改传播到数据库使用Session。

2.)Hibernate文档说:“如果给定实例未保存,请保存它的副本并将其作为新的持久实例返回。” 就你而言,由于你试图“合并”一个全新的实例,Hibernate将首先将它保存到数据库,然后重新获取它作为一个新的实体实例。返回代理的原因是因为Hibernate在默认情况下延迟加载任何Collection。为了确保集合的getter方法返回实际集合。 Hibernate创建一个代理。

3.)我很好奇你为什么不在这里使用Session.save()。

+0

也许你错过了它是JPA与Hibernate作为基础impl,而不是纯Hibernate。 – 2012-12-16 04:46:55

+0

@OndraŽižka - 我的评论仍然很好。 'merge()'方法,无论是从JPA的'EntityManager'还是Hibernate的'Session'都使用相同的方式。 – 2012-12-19 11:27:52

+0

没有冒犯,但它呈现1)无效,因为没有别的东西可以使用,3)因为没有保存()。感谢您回答2)。关于3),似乎我只需要习惯merge()的这种行为... – 2012-12-19 13:10:28