JPA取消安排删除孤儿和多态集合

时间:2018-05-07 07:13:53

标签: hibernate jpa

请查看代码。

    for (CowRow row : entity.getCowRows()) {
        em.remove(row.getCowRowData());
        em.remove(row);
    }
    entity.getCowRows().clear();

其中

@Entity
@Table(name = "cowrow")
public class CowRow {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    private Cow cow;

    private int rowNumber;

    @OneToOne(mappedBy = "cowRow", cascade = CascadeType.ALL, orphanRemoval = true)
    private CowRowData cowRowData;
//accessors here
}

CowRowData是CowPriceTag和CowReasoning的父实体。 “实体”是包含此内容的牛:

@OneToMany(mappedBy = "cow", orphanRemoval = true)
private Collection<CowRow> cowRows;

在刷新时,此代码片段会生成一个日志:

2018-05-07 11:20:21.351 TRACE 15892 --- [nio-8080-exec-1] org.hibernate.engine.internal.Cascade    : Processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.Cow
2018-05-07 11:20:21.353 TRACE 15892 --- [nio-8080-exec-1] org.hibernate.engine.internal.Cascade    : Done processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.Cow

有更多关于级联的记录,没有关于CowRow或CowRow的记录。

但是如果我删除那个“for”循环 - 人们会希望清除一个集合会导致删除孤立的CowRow实例。但是,出于某种原因,删除会被取消,这个奇怪的日志:

2018-05-07 11:40:49.342 TRACE 19739 --- [nio-8080-exec-3] org.hibernate.engine.internal.Cascade    : Processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.Cow
2018-05-07 11:40:49.343 TRACE 19739 --- [nio-8080-exec-3] org.hibernate.engine.internal.Cascade    : Done processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.Cow
2018-05-07 11:40:49.343 TRACE 19739 --- [nio-8080-exec-3] org.hibernate.engine.internal.Cascade    : Processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.Folder
2018-05-07 11:40:49.344 TRACE 19739 --- [nio-8080-exec-3] org.hibernate.engine.internal.Cascade    : Done processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.Folder
2018-05-07 11:40:49.345 TRACE 19739 --- [nio-8080-exec-3] org.hibernate.engine.internal.Cascade    : Processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.CowRow
2018-05-07 11:40:49.346 TRACE 19739 --- [nio-8080-exec-3] o.hibernate.engine.spi.CascadingAction   : Cascading to persist on flush: ru.dz.bis.entities.CowRowData
2018-05-07 11:40:49.346 TRACE 19739 --- [nio-8080-exec-3] o.h.e.i.AbstractSaveEventListener        : Persistent instance of: ru.dz.bis.entities.CowRowData
2018-05-07 11:40:49.347 TRACE 19739 --- [nio-8080-exec-3] o.h.e.i.DefaultPersistEventListener      : Ignoring persistent instance
20

如果orphanRemoval正在工作,为什么JPA会坚持使用CowRow?我清除了Cow.cowRows,JPA应该安排这些行进行删除。并且在日志中没有提到取消调度!

好的,我们试试别的。让我们在“for”循环中执行“em.remove(row.getCowRowData())”。现在我看到了:

2018-05-07 11:54:26.869 TRACE 22914 --- [nio-8080-exec-1] org.hibernate.engine.internal.Cascade    : Processing cascade ACTION_PERSIST_ON_FLUSH for: ru.dz.bis.entities.CowRow
2018-05-07 11:54:26.870 TRACE 22914 --- [nio-8080-exec-1] o.hibernate.engine.spi.CascadingAction   : Cascading to persist on flush: ru.dz.bis.entities.CowRowData
2018-05-07 11:54:26.873 TRACE 22914 --- [nio-8080-exec-1] o.h.e.i.AbstractSaveEventListener        : Deleted instance of: ru.dz.bis.entities.CowRowData
2018-05-07 11:54:26.878 TRACE 22914 --- [nio-8080-exec-1] o.h.e.i.DefaultPersistEventListener      : un-scheduling entity deletion [[ru.dz.bis.entities.CowPriceTag#8]]

所以1)依赖orphanRemoval和手动删除之间存在差异,2)JPA由于某种原因处理级联持续存在于RowData,3)处理此持久级联时,JPA表示删除了CowRowData(为什么现在?可能是因为orphanRemoval?),4)之后,它取消了删除,就像因为这个CowRowData引用了CowPriceTag(好但它是同一个实体 - 它的子类!并且最重要的是,它被删除了!)

只有当我在循环中执行“em.remove(row)”时,代码才能按设计工作。虽然现在还不完全:删除row.getCowRowData()应该使CowRowData orphan(在CowRow-&gt; CowRowData中)并安排删除(在这种情况下类似于CascadeType.REMOVE),这不会发生。

这意味着什么?

也许orphanRemoval不适用于多态集合?或者是我?

0 个答案:

没有答案