2017-02-12 189 views
0

我有兩個實體,像這樣:hibernate從父項中刪除子項需要獲取父項的所有子項?

@Entity 
public class Parent { 
    @Id 
    @GeneratedValue 
    private Long id; 

    @LazyCollection(LazyCollectionOption.EXTRA) 
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) 
    private List<Child> childs = new ArrayList<>(); 

    ...Getter & Setter 
} 

@Entity 
public class Child { 
    @Id 
    @GeneratedValue 
    private Long id; 

    @ManyToOne(optional = false) 
    private Parent parent; 

    ...Getter & Setter 
} 

當從父刪除child,Hibernate將查詢該父母的所有兒童:

parent.getChilds().remove(child); 

我有100000+子鏈接到父。查詢所有的孩子是非常緩慢和不可接受的。

如何解決這個問題或使用其他方式?

+0

兒童的多種形式是兒童; – Antoniossss

+0

@Antoniossss恥辱給我..我真的希望你能明白我的意思:) – Alex

+0

OFC我做:)爲你準備答案。 – Antoniossss

回答

0

Hibernate必須獲取所有孩子才能準備正確的SQL - 需要知道要刪除的子元素的ID。 所以沒有辦法使用ORM的方式,你想用它來做到這一點,但如果你問自己一個問題,你會怎麼做這在普通的SQL顯而易見的解決辦法是

DELETE c FROM child c WHERE c.parent_id=parentId

休眠能夠生成這樣的查詢,但它通過HPQL完成。所以,如果你已經delcared父母和孩子之間的雙向關係,你有childparent財產,那麼你可以做以下使用HPQL:

Query q=session.createQuery(`DELETE c FROM chilc WHERE c.parent=:parent`); 
q.setObject("parent",parent); 
q.execute(); // q.executeUpdate? 

這樣你西港島線刪除父所有的孩子都沒有獲取它們。

免責聲明: 鑑於查詢可能不是100%準確,因爲我不記得Hibernate的Session API了,但對解決方案的總體看法是給定的,並且100%有效。只是想知道Hiberrnate的文檔細節。

-1

使用會話的delete方法,而不使用父母和級聯更新:

sesionFactory.getCurrentSession().delete(child); 

更新

這是刪除這樣的,以確保其管理之前執行合併一個很好的做法:

sesionFactory.getCurrentSession().merge(child); 
+0

這不會使敏感,因爲你必須去取孩子--OP想要省略:) – Antoniossss

+0

大概我應該問到更多的細節,但從問題來說,它不清楚從哪兒來的。它可以作爲參數(作爲分離的實體或仍然管理)傳遞給此方法,然後您不需要使用父級以將其刪除 –

+0

可能......但仍未100%清除 –

相關問題