Hibernate级联删除不起作用

时间:2017-04-24 12:05:20

标签: java hibernate cascade

我有3个实体:' Person',' Document',' PersonDocument'其中涉及如下:

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已消失,但相关的documents仍保留在数据库中。为什么会这样?

2 个答案:

答案 0 :(得分:1)

级联操作不会那样。

当您使用@Cascade注释时,在父级中进行的操作将级联到子级别,这取决于级联类型。

由于您的课程使用CascadeType.ALL进行注释,因此在父课程中所做的所有操作将级联到子级。

因此,要使删除工作,您需要调用entityManager.remove(person),然后持久性提供程序也会调用子级中的删除。

话虽如此,将代码更改为类似的东西:

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);   

答案 1 :(得分:0)

尝试 CascadeType.DELETE 而不是 CascadeType.ALL

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