gpt4 book ai didi

java - JPA 如果失败则尝试删除设置为非 Activity 状态

转载 作者:行者123 更新时间:2023-12-01 11:26:51 26 4
gpt4 key购买 nike

我有以下实体 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com