我有两个具有一对一关联的实体。以及与它们并行工作的某些服务。我需要删除一个实体,但是有时我有DataIntegrityViolationException,据我了解,这意味着我无法删除某个实体,而另一个实体上却带有外键。
这是我的实体:
public class Foo{
@Id
@GeneratedValue
private Long id;
}
和:
public class Bar{
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Foo foo;
}
无效的方法(所有存储库均从JpaRepository扩展):
@Transactional
public void deleteFoo(Long fooId) {
barRepository.deleteAllByFooId(fooId);
fooRepository.deleteById(fooId);
}
和一些并行工作并破坏一切的方法
@Transactional
public void method(Long fooId) {
...
Foo foo = fooRepository.findById(fooId);
barRepository.save(new Bar(foo));
...
}
所以我有ConstraintViolationException,据我了解,因为我试图删除Foo,但是我在new Bar(foo)
中拥有method
,而barRepository.deleteAllByFooId(fooId)
在deleteFoo
中没有删除。
我需要某种方法,例如“删除方法应等到所有当前事务完成后才运行一个事务”。
无法使用KeyLockManager
,因为项目的实际结构已经足够复杂,如果我使用它,那么它在许多类中应该是相同的锁。
答案 0 :(得分:-2)
问题是您尝试删除在事务中使用的实体。要关闭交易,您可以使用存储库的save()
方法。
您还应该查看cascades和orphan removal。像这样使用:
在Bar
实体中:
@ManyToOne(cascade = CascadeType.REMOVE, orphanRemoval = true)
private Foo foo;
然后像这样删除:
barRepository.save(bar);
等等: