当我尝试使用Hibernate删除实体时,没有错误消息但没有删除

时间:2019-03-30 10:01:09

标签: java spring hibernate jpa

我有三个实体,BagItemCategory。一个Bag可以有很多Items,许多Items可以有很多Categories

Bag <---- OneToMany ----> Item

Item ----- ManyToMany -----> Category

没必要将items存储在Category

当我尝试删除没有Item的{​​{1}}时,没有任何错误消息,但是categories并没有被删除。但是,如果我尝试在数据库中删除相同的Item,则会成功删除它。

另一方面,如果我尝试使用item删除Item,则会收到此错误消息:

“无法删除或更新父行:外键约束失败(categories,约束item_categories外部键(fk_item_categories_items_id)参考items_id({{1} }))”。

我想删除item及其与他的id的关系,但保留item。我该怎么办?

对于第一个问题,我尝试将其添加到删除方法categories中,但是它仅删除两者之间的关系,并且categories在DB中继续。

  

Bag.java

bag.removeItems(item)
  

Item.java

item
  

ItemResource.java

    @OneToMany(mappedBy = "bag", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JsonIgnoreProperties("bag")
    private Set<Item> items = new HashSet<>();

编辑: 创建和更新的方法工作正常。

1 个答案:

答案 0 :(得分:0)

因此,问题是您通过中间(或关联)表解决了多对多关系,在该表中存储了对item-category对。 当您删除项目时,将执行实际的DELETE FROM item查询,但是由于存在外键约束,该查询不允许对应的对保持孤立状态,因此查询失败。

要解决此问题,您可以简单地自己删除关联:

item.getCategories().clear();

必须在哪里执行此代码,由您决定。您可以在Item内部创建一个钩子,如下所示:

@PreRemove
private void deleteCategories() {
    this.getCategories().clear();
}

或者您可以创建将执行类似操作的ItemService

public void deleteItem(Long id) {
    final Item item = itemRepository.findById(id);
    // you can handle here when not found, which is a good thing to do
    item.getCategories().clear();
    itemRepository.deleteItem(item);
}

或者您可以为JPA存储库实现一个自定义方法,我不喜欢这种方法,但是您可以在How to add custom method to Spring Data JPA上进行阅读。