2017-04-24 105 views
1

我有3個實體:「人」,「文件」,「PersonDocument」這關係如下:Hibernate的級聯刪除不起作用

class Person { 
    @Cascade(CascadeType.ALL) 
    @OneToMany(mappedBy = "person", orphanRemoval = true, fetch = FetchType.LAZY) 
    Set<PersonDocument> personDocuments; 
} 

class Document { 
    @OneToMany(mappedBy = "document") 
    Set<PersonDocument> personDocuments; 
} 

@IdClass(PersonDocumentPK.class) 
public class PersonDocument { 
    @Id 
    private Person person; 
    @Id 
    private Document document; 

    @ManyToOne(fetch = FetchType.LAZY) 
    private Provider provider; 
} 

public class PersonDocumentPK implements Serializable { 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "person_guid") 
    private Person person; 

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    @JoinColumn(name = "documents_guid") 
    private Document document; 
} 

在我的代碼,我想從Person#personDocuments刪除一些記錄並添加新的記錄。我這樣做,如:

Iterator it = person.getPersonDocuments().iterator(); 
PersonDocument pd = it.next(); 
if (some logic) it.remove(); 
... 
person.getPersonDocuments().addAll(new set of values);  

在結果取出personDocuments已經disappeard,但相關的documents留在數據庫中。爲什麼如此?

回答

0

嘗試CascadeType.DELETE,而不是CascadeType.ALL

@Cascade({CascadeType.SAVE_UPDATE,CascadeType.DELETE})

+0

在這種情況下,我得到異常:'從model.entity.PersonDocumentPK被改變model.entity.PersonDocument的一個實例的標識@ f224a1f1 to model.entity.PersonDocumentPK @ de57b5f' –

+0

你可以看到mkyoung例子https://www.mkyong.com/hibernate/hibernate-cascade-example-save-update-delete-and-delete-orphan/,你也可以直接從mysqlWorkbech中將cascad刪除 –

1

級聯操作不象是那樣工作。

當您使用@Cascade註釋時,根據級聯類型,父級中執行的操作將級聯到子級聯。

由於您的班級注有CascadeType.ALL,因此在父級中所做的所有操作都會級聯到孩子。

因此,要刪除工作,您需要撥打entityManager.remove(person),然後持久性提供程序也會調用子項中的刪除。

話雖這麼說,改變你的代碼,以somethng這樣的:

Iterator it = person.getPersonDocuments().iterator(); 
PersonDocument pd = it.next(); 
if (some logic) { 
    it.remove(); 
    em.remove(pd); // No problem to call in the loop because it will call the database only on commit or flush 
} 
... 

person.getPersonDocuments().addAll(new set of values);