我有以下类别:休眠删除已存在的无序
类别
@Entity
@Table(name = "category", schema = "customer")
public class Category extends CustomerOwned {
...
}
CatalogueItem
@Entity
@Table(name = "catalogue_item", schema = "customer")
@EntityListeners(value = { CatalogueItemStatusListener.class })
public class CatalogueItem extends CatalogueOwned implements Statusable<CatalogueItem, CatalogueItemStatus> {
...
@OneToMany(mappedBy = "catalogueItem", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<CatalogueItemCategory> categories;
...
}
CatalogueItemCategory
@Entity
@Table(name = "catalogue_item_category", schema = "customer")
public class CatalogueItemCategory extends CatalogueItemOwned implements CategoryOwner {
...
@ManyToOne
@JoinColumn(name = "category_id", nullable = false, insertable = true, updatable = false)
private Category category;
...
}
我们在应用程序中执行很少硬删除,但类别 s的硬删除。 CatalogueItemCategory s也被硬删除。
我创建一个服务,允许有人要删除类别,并在同一时间,我检查所有类别的依赖关系,并删除这些呢,所以我这样做:
@Transactional
public DependentItemsResultResource delete(String categoryId, boolean force) {
List<CatalogueItem> catalogueItems = catalogueItemRepository.getByCategory(getCustomerStringId(), categoryId);
DependentItemsResultResource resultResource = new DependentItemsResultResource();
resultResource.setDependentCatalogueItems(new SearchResponse().from(catalogueItems, CatalogueItemSummaryResource::new));
if (!catalogueItems.isEmpty()) {
if (!force) {
resultResource.setDeleted(false);
return resultResource;
}
catalogueItems.forEach(item -> {
item.getCategories().removeIf(catalogueItemCategory -> categoryId.equals(catalogueItemCategory.getCategory().getStringId()));
sendEvent(prepareEvent(new CatalogueItemUpdatedEvent(), item.getCatalogue().getStringId(), item.getStringId()));
});
}
Category category = getCategory(categoryId);
resultResource.setDeleted(true);
categoryRepository.delete(category);
CategoryDeletedEvent event = new CategoryDeletedEvent();
event.setCategoryPath(category.getPath());
sendEvent(prepareEvent(event, categoryId));
return resultResource;
}
这导致以下情况除外:
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FKLYKUEHJG9UL0LR36O5XDD3MLF: CUSTOMER.CATALOGUE_ITEM_CATEGORY FOREIGN KEY(CATEGORY_ID) REFERENCES CUSTOMER.CATEGORY(ID) (1)"; SQL statement:
delete from customer.category where id=? [23503-192]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:426)
at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:443)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:318)
at org.h2.table.Table.fireConstraints(Table.java:967)
at org.h2.table.Table.fireAfterRow(Table.java:985)
at org.h2.command.dml.Delete.update(Delete.java:101)
at org.h2.command.CommandContainer.update(CommandContainer.java:98)
at org.h2.command.Command.executeUpdate(Command.java:258)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:160)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:146)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 109 common frames omitted
我试过更换该位:
item.getCategories().removeIf(catalogueItemCategory -> categoryId.equals(catalogueItemCategory.getCategory().getStringId()));
与此:
item.getCategories().stream()
.filter(catalogueItemCategory -> categoryId.equals(catalogueItemCategory.getCategory().getStringId()))
.forEach(catalogueItemCategoryRepository::delete);
但它没有任何区别。 Hibernate正在按顺序删除对象。它应该删除类别对象之前之前的CatalogueItemCategory对象,但它不是。
如何以正确的顺序删除它?
编辑:错过了这个类提供了CatalogueItemCategory的父:
@MappedSuperclass
public class CatalogueItemOwned extends Updateable {
...
@ManyToOne
@JoinColumn(name = "catalogue_item_id", nullable = false, insertable = true)
private CatalogueItem catalogueItem;
...
}
没有指定没有父子关系的OneToMany关系的CascadeType.REMOVE的行为。 – fg78nc
我应该指出,我试着在List上玩CascadeType,除了完全删除它并且没有任何帮助,并且当我这样做时,CatalogueItemCategory对象停止在列表中保持持续(在前面的“添加”操作期间) 。我尝试的第一件事是删除CascadeType.REMOVE。 –
Richtopia
orphanRemoval = true会隐式切换CascadeType.REMOVE – fg78nc