2012-07-22 70 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