当前位置: 首页 > 知识库问答 >
问题:

刷新和持久存在于单个事务中的多个约束违反

左丘嘉木
2023-03-14

我试图使用JPA(EclipseLink)在一个事务中保存多个记录。该条目在DB上定义了主键。

我的提要中有一些重复项,因此我知道将存在违反约束的情况。我希望捕获单个项的约束冲突异常,并继续持久化其他项。

这是我的密码:

实体:

@Entity
@Table(name="TEST")
public class TestEntity {

    @Id
    private String name;

    public TestEntity() {

    }

    public TestEntity(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

操作:

@Transactional
public void test() {

    List<String> list = Arrays.asList("A", "B","C","D","D","E","F","G");//duplicated D

    for(String name: list) {
        try {
            TestEntity entity = new TestEntity(name);
            logger.info("" + entity);
            entityManager.persist(entity);
            logger.info("Persist done");
            entityManager.flush();
            logger.info("Flush done");
        } catch(RuntimeException e) {
            logger.warn("Entry {}  was skipped due to following exception {}.",  name, e.getLocalizedMessage());
        }
    }

    logger.info("Importing dictionary finished. ");
}

结果,我得到了第二个D的约束冲突异常(这是我所期望的),但我也得到了下一个项目的这个异常,这是我不理解的事情。

我得到:内部异常:java。sql。SQLIntegrityConstraintViolationException:ORA-00001:违反了唯一约束(BBHDEV4.SYS_C0023890)

是什么导致了这个问题?

共有2个答案

封昊天
2023-03-14

问题是第二个D仍然是同一个Transaction/Unit of Work的一部分,因此在接下来的迭代中,hibernate尝试再次保存它。

要解决这个问题(使用vanilla JPA),您可以

  • 为要更新的每个项目创建一个新事务

对于hibernate,你有第三个选择,那就是使用无状态会话,但是我不知道eclipselink是否有无状态实体管理器的概念

公冶智刚
2023-03-14

实体管理器维护由所有托管实体(即持久性上下文)及其对象的事务状态组成的状态。

因此,在触发约束冲突的刷新之后,D实体仍然处于管理状态和过时状态,并且将在下一次显式刷新调用(您不应该显式调用flush)或当前事务结束时再次刷新。在恢复循环之前,必须手动从持久性上下文(detach())中逐出D实体。

无论如何,如果您的所有操作都是同一事务的一部分,并且错误被抛出事务边界之外,那么事务管理器将自动回滚整个事务。

事务是一个工作单元,如果您不想让不同的操作独立,那么必须在不同的事务中执行它们。通常,实体管理器的作用域与事务管理器的作用域相同(至少当由容器管理时,即注入@persistencecontext),您将同时解决这两个问题。

 类似资料:
  • 我有一个物品清单。它们是JPA“位置”实体。 我有一个无状态EJB,它在列表中循环并持久化每一个。 代码运行良好。我没有任何问题。然而,问题是:我希望这是一个全有或全无的交易。当前,每次通过for循环,persist()方法都会在数据库中插入一个新行。假设我有100个location对象,而第54个对象有问题,并且抛出了一个异常。将有53条记录插入数据库。我想要的是:在任何一个成功之前,他们必须全

  • 问题内容: 在使用hibernate和MySQL的spring mvc应用程序中,我收到以下约束冲突异常: 当我尝试保存一个包含type的属性时,会出现问题,这两个属性都在下面定义。 我已经读过很多关于此错误的帖子和博客,但似乎没有一个可以解决我的问题。 如何解决此错误? 这是课程: 这是课程: 这是来自控制器的代码: 这是dao方法: 已执行的SQL语句和hibernate试图通过sql插入的实

  • 我的桌子有两个独特的列: 我想写保存或更新方法 My jooq code: 但我遇到了异常: “错误:没有唯一或排除约束匹配ON CONFLICT规范” 请帮助。

  • 我正在使用Hibernate 4.0最终版和ojdbc6来开发我的网络应用程序。一切都好,除了当我试图插入一个新的父母/孩子的关系。首先,这些是实体: 让我们看看这两个场景: 员工已存在,我尝试向其添加新地址-- 这是事务处理程序: 你可以想象,2.b的案子是我关心的。我已经调试了事务,这是我调用保存()方法(在DAO类中)时得到的: 会议结束了。saveOrUpdate(employee)方法成

  • 问题内容: 有没有一种方法可以使用JPA指定在不同的列集上应该有多个唯一约束? 我已经看到了特定于hibernate的注释,但是由于我们仍在确定hibernate和数据核之间的关系,因此我试图避免使用特定于供应商的解决方案。 问题答案: 所述的属性实际接受的这些阵列。您的示例只是具有单个元素的数组的简写。否则,它看起来像: 只要唯一性约束仅基于一个字段,就可以在该列上使用。

  • 我目前正在实现一个基于 JavaEE 的应用程序,其结构大致如下: webservice接收请求并将它们转发给实际的业务服务,然后业务服务通过DAO执行多个操作。重要的是,BusinessService必须使用只能通过业务代码表达的约束,而不是通过SQL约束(我们不希望实现复杂的数据库触发器或存储过程)来对照现有记录检查数据。在这种情况下,约束是没有两个数据集可能具有重叠有效性。 对于最小方案,代