我有以下实体 A(将 B 想象为一个简单的实体,具有可以被其他实体引用的 Activity/非 Activity 标志)
@Entity
public class A {
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
private B b;
}
我需要尝试删除 b,但如果它被其他实体引用,我想退回到停用它。
想象一下这样的事情
public void removeB() {
B toRemove = this.b;
this.b = null;
try {
entityManager.remove(toRemove);
entityManager.flush();
} catch (ConstraintViolationException e) {
toRemove.setActive(false)
}
}
问题是这给了我错误
Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
知道如何实现这个目标吗?
编辑
我的问题不是向用户显示错误消息,因为我找到了可以做到这一点的库
https://blog.42.nl/articles/recovering-from-database-constraint-violations-in-java/
我的问题是从删除中可能发生的任何异常中恢复
最佳答案
更好的方法(只是想法,详细信息取决于 JPA 提供商):
public void deleteB(B b) {
Long count = entityManager.createQuery("select count(a) from A a where a.b.id = :b")
.setParameter("b", b.getId())
.getSingleResult):
if (count == 0L) {
// delete B
} else {
// make B inactive
}
}
处理您的具体案例:
在您的示例中,您有一个 RollbackException,这表明持久上下文同步操作(在您的示例中很可能是刷新)失败并标记了整个事务以进行回滚.
事情发生后你没有什么好的处理办法。但是,您可以尝试在交易失败之前进行预测。例如,尝试在另一个事务中删除B,看看删除是否会失败。这是一个肮脏的伎俩,但似乎是数据库 api 设计的唯一方法。
关于java - JPA 如果失败则尝试删除设置为非 Activity 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30753931/