2011-06-03 42 views
0

意外插入我有兩個對象之間一個非常基本的關係:執行的EclipseLink在許多一對一的關係

@Entity 
public class A { 

    @ManyToOne(optional = false) 
    @JoinColumn(name="B_ID", insertable=false, updatable=true) 
    private StatusOfA sa; 

    getter+setter 
} 

@Entity 
public class StatusOfA { 

    @Id  
    private long id; 

    @Column 
    private String status; 

    getter+setter 
} 

這裏只有在DB一組有限StatusOfA的。
我在事務執行上的一個更新:

@TransactionalAttribute 
public void updateStatusOfA(long id) { 
    A a = aDao.getAById(123); 
    if(a != null) { 
    a.getStatusOfA().getId(); //just to ensure that the object is loaded from DB 
    StatusOfA anotherStatusOfA = statusOfADao.getStatusOfAById(456); 
    a.setStatusOfA(aontherStatusOfA); 
    aDao.saveOrPersistA(a); 
    } 
} 

的saveOrPersistA方法在此合併 'A'。

我希望Eclipselink只執行'a'上的更新來更新StatusOfA,但它正在執行StatusOfA表上的新插入。然後Oracle因爲違反了一個獨特的違反規定而抱怨(Eclipselink試圖保留的StatusOfA已經存在......)。 這裏沒有Cascading,所以問題不在那裏,Hibernate(在JPA2中)的行爲如同例外。
在同一個項目中,我已經做了一些更復雜的關係,我真的很驚訝地發現這裏的關係不起作用。
在此先感謝您的幫助。

回答

0

是什麼,statusOfADao.getStatusOfAById()呢?

它使用相同的持久化上下文(相同的事務和EntityManager)嗎?

您需要使用相同的EntityManager,因爲您不應混合來自不同持久性上下文的對象。

saveOrPersistA做了什麼? merge()調用應該可以正確解決所有問題,但是如果你真的弄糟了對象,可能很難像你期望的那樣合併所有東西。

你合併了A還是它的狀態?也嘗試將狀態設置爲狀態的合併結果。

+0

感謝您的回覆 所有的daos共享同一個實體管理器。 getStatusOfAById執行query.getSingleResult()。 這兩個對象「a」和「anotherStatusOfA」還連接實體。據我瞭解的持久性機制,合併甚至不需要...... – Jodenis 2011-06-07 13:23:45

0

假設: @標識@ GeneratedValue(策略= GenerationType.IDENTITY)


讓我們考慮statusOfADao.getStatusOfAById以下實現(456):

1.回報「代理」對象,只有id設置:

在新事務

2.返回實體:

EntityManager em = emf.createEntityManager();em.getTransaction().begin(); 

StatusOfA O = em.find(StatusOfA.class,456); // em.getReference(StatusOfA.class,456); em.getTransaction()。commit(); return o;

3。返回離散的實體:

StatusOfA o = em.find(StatusOfA.class,456);//em.getReference(StatusOfA.class,456); 
em.detached(o); 
return o; 

4.返回反序列化序列化實體:

return ObjectCloner.deepCopy(em.find(StatusOfA.class,456)); 

5.返回附實體:

return em.find(StatusOfA.class,456); 

結論:

  1. 的EclipseLink只處理實現N5作爲 「預期」。
  2. 休眠處理所有五個實現的「預期」。
  3. 什麼樣的行爲沒有analisys是JPA規範兼容
+0

的EclipseLink不分離對象支持引用,但混合管理和分離對象是不推薦的東西,一般的事情。 merge()應該用來解析分離的對象。 JPA規範,我相信允許只在不堅持級聯分離對象的引用,否則需要一個錯誤被拋出。一般混合引用分離對象是不是一個好主意,因爲分離對象將不反映對象的,目前的管理狀態。 – James 2011-06-13 15:37:16