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

标签 java hibernate jpa

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

相关文章:

javascript - 如何获得后退按钮链接以返回原始搜索页面?

java - 修改 ConcurrentHashMap 中的值

java - 如何在 session 中存储检索对象并在之后访问它?

java - Spring Data JPA Lazy 加载注释为 Eager 的集合

java - 使用 JPA 2.0 Criteria API 选择定义集的超集数据

java - Hibernate\JPA 在高并发 Web 应用程序上的使用

java - array 没有在循环中获取值

java - Swing 油漆法

java - 对象属性的 Hibernate 条件/查询

Hibernate 的 Java 类型转换