2017-04-24 108 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);