2016-01-25 55 views
0

我必須處理循環依賴關係,我不能影響,我對JPA相當陌生。持續循環依賴實體

所以一個實體有相同的實體的成員,我下定決心,通過:

@Entity 
@Table("A") 
public class A { 
    @ManyToMany 
    @JoinTable(name = "A_HAS_SUBAS", 
     joinColumns = {@JoinColumn(name = "A_ID")}, 
     inverseJoinColumns = {@JoinColumn(name = "SUBA_ID")}) 
    private Set<A> as; 
} 

當寫入DB我有休眠似乎並不知道其中A首先必須堅持的問題。我試圖通過從A中刪除所有關係,寫入數據庫並通過休眠恢復關係來解決此問題。

這似乎工作,但似乎失敗,如果A沒有SubAs,這不符合我對這個問題的理解。所以我肯定在某個地方是錯的。

沒有關係的實體是由內部交易持續:

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
private void immediatelySaveNewEntity(A entity) { 
    try { 
     if (!dao.entityExistsFromId((int) entity.getId())) { dao.save(entity); } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

因此,我得到一個

ORA-02291:完整性約束(...)侵犯 - 父鍵不發現

我可以通過從數據庫中刪除約束來規避此問題,但這不是我處理此問題的首選方式。

回答

0

好吧,這對我來說是一種心靈上的彎曲,但我的方法沒有問題,只是有一點小小的錯誤。

我有循環依賴實體。在寫入數據庫之前,我將所有關係從實體中刪除,並將其保存到數據庫中,然後作爲更新恢復關係。這沒關係,因爲通過這種方式,我擁有了數據庫中的所有實體,並且可以輕鬆地恢復循環依賴關係。 我希望我能擺脫他們擺在首位,但沒有。

錯誤是在如何我做到了。由於只有一個事務,關係的去除沒有任何效果,因爲當擁有所有關係的實體最終持久化到數據庫時,我已經恢復了以前的狀態。 我試圖用一個新的事務與

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 

但在相同的豆,我學會了如何艱難地在同一個事務。 提示來自Strange behaviour with @Transactional(propagation=Propagation.REQUIRES_NEW)

因此,我注入了同一個bean的新實例,並在此實例上執行了新的事務,並訪問了代理,並且工作良好。

0

我沒有在類A中聲明任何@Id屬性聲明。我相信你可能爲了簡潔而刪除它。

您可以嘗試更新@ManyToMany@ManyToMany(cascade=CascadeType.ALL),如下所示並嘗試。

@Entity 
@Table("A") 
public class A { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    @ManyToMany(cascade=CascadeType.ALL) 
    @JoinTable(name = "A_HAS_SUBAS", 
      joinColumns = {@JoinColumn(name = "A_ID")}, 
      inverseJoinColumns = {@JoinColumn(name = "SUBA_ID")}) 
    public Set<A> as; 
} 

能夠用下面的hibernate測試代碼保存它,並且應該可以使用JPA。

Session sess = //Get Session 
Transaction tx1 = sess.beginTransaction(); 

A a = new A(); 
a.as = new HashSet<>(); 
a.as.add(new A()); 
a.as.add(new A()); 
sess.persist(a); 
tx1.commit(); 

Incase我得到了你的測試場景錯誤,發佈你的基本測試場景會有所幫助。