请查看代码。
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不适用于多态集合?或者是我?