2013-11-27 52 views
2

我一直認爲可以歸結爲類似的東西,一個實體設置:如何合併等於()但不完全相同的兩個分離實體?

Person (N:1) -> Job (1:N) -> Company 

所以一個人有Jobjava.util.Set實例。該組的定義是這樣的:

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true) 
private Set<Job> jobs = new LinkedHashSet<>(); 

而且公司看起來是這樣的:

@Entity 
public class Company { 
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
    @Column(nullable = false, unique = true) 
    private String name; 
    @OneToMany 
    private List<Stelle> jobs = new ArrayList<Stelle>(); 

    public String getDisplayText() { return name; } 
    @Override 
    public int hashCode() { 
     int result = 1; 
     result = 31 * result 
      + ((getDisplayText() == null) ? 0 : getDisplayText().hashCode()); 
     return 31 * result + ((getId() == null) ? 0 : getId().hashCode()); 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (!(obj instanceof Company)) 
      return false; 
     return !(getId() == null && ((Company) obj).getId() != null) 
      || getId() == null 
      || (getId().equals(((Company) obj).getId()); 
    } 
    // getters + setters 
} 

我創建並在我的前端連接的工作對一個人的實例。選擇該公司並將其附加到具有​​的新實體Job實體中,其中通過其ID從持久性上下文中提取該實體。

當我打電話entityManager.merge(person)上有兩個Job s的相同Company一個人,我得到這個異常:

Caused by: java.lang.IllegalStateException: Error occurred while storing 
    entity [example]. An entity copy [com.company.entity.Company#1] was already 
    assigned to a different entity [example]. 
at org.hibernate.event.internal.EventCache.put(EventCache.java:192)  
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:287) 
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:153) 
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:851) 
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:833) 
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:277) 
[...] 

我的問題似乎來是DefaultMergeEventListener.java:113(休眠-4.3.0.CR1 )說:

if (copyCache.containsKey(entity) && 
     (copyCache.isOperatedOn(entity))) { 
    LOG.trace("Already in merge process"); 
    event.setResult(entity); 
} 
else { /* fetch entity and put it in copyCache */ } 

copyCachejava.util.IdentityHashMap,所以我的兩個分離的實體不是被認爲是相同的這個緩存,即使他們是根據他們的equals()方法。

我的問題很簡單:我能以某種方式繼續使用上面描述的流程,或者我需要改變什麼才能讓Hibernate合併此實體圖形?

編輯添加:我知道Hibernate: An entity copy was already assigned to a different entityIllegalStateException: Error occurred while storing entity <entity> An entity copy <entity> was already assigned to a different entity <entity_copy>描述類似的問題。

+1

檢查鏈接::: http://stackoverflow.com/questions/10550511/illegalstateexception-with-hibernate-4-and-manytoone-cascade – dev

+0

@Purnendu很好找,這是同樣的問題。不過,提到「降級」作爲工作解決方案。 – mabi

+0

從鏈接的問題,它更像是「修復你的應用程序代碼」。這意味着「緩存轉換器中'公司'的每個可見實例」。會是一個相當悲傷的結果。我希望解釋爲什麼Listener中的限制首先是如此困難。 – mabi

回答

2

我得到了這樣的問題早,我在休眠文件:::使用下面的代碼

Session session = getSession(); 
if(pojo.id!=null){ 
    session.merge(pojo) 
} 
else{ 
    session.saveOrUpdate(pojo) 
} 

其中的getSession()是

public Session getSession() { 
    Session session = getSessionFactory().getCurrentSession(); 
    if (session == null) { 
     session = getSessionFactory().openSession(); 
    } 
    return session; 
} 
+0

謝謝,但我沒有關注。什麼是「pojo」?我的人?在我正在測試的情況下,這個人總是有一個'id'集合,所以'saveOrUpdate'分支永遠不會被調用。 – mabi

+0

pojo是你的實體公司 – dev

+0

所以你建議我自己走對象圖並在調用person對象上的merge之前手動合併實體?這將是非常不幸的,我期望'cascade = ALL'能爲我做到這一點。 – mabi

相關問題