Spring JPA存储库删除方法不起作用

red*_*ist 3 java spring hibernate jpa

我无法让 Spring JPA 使用 jpa 存储库删除方法删除 bar 实体。
谁能看出问题出在哪里吗?

不起作用:

barRepository.delete(bar.id);
Run Code Online (Sandbox Code Playgroud)

Jpa 存储库:

public interface BarRepository extends JpaRepository<Bar, Integer>
Run Code Online (Sandbox Code Playgroud)

Hibernate 实体映射(仅相关部分):

@Entity(name = "foo")

@OneToMany(fetch = FetchType.EAGER, mappedBy = "foo", cascade = CascadeType.ALL, orphanRemoval = true)
@Fetch(FetchMode.SELECT)
private List<Bar> bars = new ArrayList<>();

@Entity(name = "bar")

@ManyToOne(optional = false)
@JoinColumn(name = "foo_id")
@Fetch(FetchMode.SELECT)
private Foo      foo;
Run Code Online (Sandbox Code Playgroud)

编辑:具有最小可重现示例的 git repo。 HibernateDeleteApplicationTests.java包含测试用例。

https://github.com/matijaivanus/hibernate-delete-problem

M. *_*num 14

“问题”是你的映射。您的收藏已被热切检索。现在为什么这会成为一个问题。Spring Data JPA 中的deleteById首先会执行一个操作findById,在您的情况下会加载BarFoo急切地加载内部的集合Foo

现在Bar尝试删除它,但由于它仍然被另一个实体附加和引用,它将再次被持久化,因此删除被取消。

为了解决你有3个选择

  1. 使用查询删除并为此编写自己的查询方法
  2. 正确删除Barfrom Foo,将关系设置为null,然后持久化Foo或删除Bar
  3. 将关联的任一侧标记为惰性(这仍然可能因 1 而失败)。

其中任何一个都会起作用。第一个是因为它绕过了 JPA 缓存机制,第二个是因为现在关联已被切断。第三种方法可以工作,但如果对象已经加载,就会遇到与 1 相同的问题。