2014-07-03 39 views
0

我嘗試編寫一個JPQL查詢,它刪除了另一個實體集合中的所有實體。 (示例代碼,沒有的getter/setter和註釋)JPQL DELETE查詢:刪除另一個實體列表中的實體

class Aa implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String value; 
} 

@Entity 
class A implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @JoinColumn(nullable = false) 
    @OneToOne 
    private Aa aa; 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    private List<B> data; 
} 
@Entity 
class B implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 


    private String value; 
} 

我曾嘗試以下:

DELETE FROM B b WHERE b.id IN(SELECT k.id FROM A a JOIN a.data k WHERE a.id = :id) 

但它的外鍵衝突異常結束。 另一種方法是

DELETE FROM B b WHERE EXISTS(SELECT a FROM A a WHERE a.id = :id) 

,但其在外國鍵衝突也結束。

但是如果我執行一個SQL查詢直接對數據庫進行,像

DELETE FROM B WHERE id = <a id number here> 

,那麼不發生錯誤...

EntityManager.remove()是不是一種選擇,因爲我要刪除大量的數據。

我很感謝你的回答和幫助。

回答

0

好,用Syfors的建議幫助我有改變A和B之間的關係:

class Aa implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String value; 
} 

@Entity 
class A implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @JoinColumn(nullable = false) 
    @OneToOne 
    private Aa aa; 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, mappedBy = "owner") 
    private List<B> data; 
} 
@Entity 
class B implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @OneToOne 
    private A owner; 


    private String value; 
} 

我還發現:

[...]一般而言,這是最好的在Java中定義多對一回參考[...]

來源:http://en.wikibooks.org/wiki/Java_Persistence/OneToMany

現在JPA不會產生THRID表爲M:1間的關係,現在我的JPQL查詢工作正常:

DELETE FROM B b WHERE b.id IN(SELECT k.id FROM A a JOIN a.data k WHERE a.id = :id) 
0

由於我沒有足夠的聲望,無法添加評論。

您跳過註釋,這很重要,因爲它有助於瞭解哪個方面,父母,孩子或他們之間的某個東西是否處於關係控制之中。例如,如果父方正在控制,在某些情況下,只需在父節點上清空List並堅持刪除其子節點就足夠了。所以更多的代碼會有幫助。

編輯1:

如果你正在使用JPA 2.0你可以添加orphanRemoval="true"@OneToMany。然後,從持久性獲得父母,執行parent.getData().clear(),然後執行EntityManager.merge(parent)或讓孩子知道關係。您正在嘗試移除不知道其父母的孩子,所以我建議您通過父母或通過提醒他們注意。

+0

你是對的。我在主帖中添加了註釋。母方正在控制關係。但是我有大量的A對象存儲大量的B對象。這就是我使用DELETE語句的原因。 – user2429841

+0

檢查編輯,增加了一些建議。 – Candyman

+0

問題是,如果我打電話給家長。getData(),然後選擇列表中的所有實體(它不管是取類型laze還是渴望)。我試圖阻止這一點。 – user2429841

相關問題