【问题标题】:JPA batch insert causing ConstraintViolationExceptionJPA 批量插入导致 ConstraintViolationException
【发布时间】:2015-05-05 15:10:29
【问题描述】:

我正在从事主要使用 EJB 和 JPA 的项目,但我遇到了不应发生的 ConstraintViolationException 问题。

首先,我有 MyEntity 类,其中 @Id 和几个唯一字段。 我有@Stateless MyEntityRepository 类和find() 方法,它只是通过调用EntityManager get() 方法返回MyEntity(或null)。 另一个@Stateless bean 是SaveEntityBean

@Stateless
public class SaveEntityBean {

    @Inject
    EntityManager em;
    @Inject
    MyEntityRepository repository;

    public void saveEntity(MyEntity me) {
        if(repository.find(me) == null) {
            //the place with ConstraintViolationException
            em.persist(me);
        }
    }
    public void saveEntities(List<...> entities) {
        for(MyEntity me: entities)
            saveEntity(e);
    }
}

并且方法saveEntities(List&lt;...&gt; entities)是从另一个bean调用的:

@Stateless
@Startup
public class SaveEntityBean {

    @Inject
    SaveEntityBean saveBean;
    //...

    @Schedule(hour = "*", minute = "*", second="*/5")
    @AccessTimeout(unit = TimeUnit.MINUTES, value = 1)
    public void mainLogicMethod() {
        List<MyEntity> entities = io.calculateAndGetEntities();
        saveBean.saveEntities(entities);
    }
}

io.calculateAndGetEntities() 方法是长 IO 工作。问题是有时我会得到org.hibernate.exception.ConstraintViolationException,我认为这不应该发生,因为我在调用persist() 方法之前检查了MyEntityRepository.find(me) != null 条件。 我唯一的想法是提交之间有一些延迟,所以在条件检查中调用MyEntityRepository.find(me)方法后,提交发生,然后persist()方法抛出异常。

请给我任何建议阅读和学习什么以及如何解决问题。

编辑: 我发现这是线程的问题,所以解决方案可能是锁定写/读。

【问题讨论】:

  • 确实它看起来像一个同步问题 - 你在 saveEntity() 中有一个检查然后执行操作,而 mainLogicMethod() 计时器产生线程。
  • 当我发现变量 me 和 em 在同一个范围内时,我停止了阅读。

标签: java hibernate jpa ejb


【解决方案1】:

好的,通常在高并发环境中,很难解决这个问题,简单地锁定将不起作用(并且您不想使用表锁)。现在我使用来自org.hibernate.annotations.SQLInsert 的Hibernate @SQLInsert 注释,所以我的实体看起来像这样:

@SQLInsert(sql = "INSERT INTO my_entity_table(a, b, c) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE a=a;")
public class MyEntity implements Serializable {...}

当您想向用户显示一些错误消息时,当然会出现问题,但在我的情况下已经足够了。 据我所知,该 SQL 语句仅在 MySQL 中受支持,在其他 RDBMS 中您应该使用不同的方法。

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 2017-08-23
    • 2017-08-11
    • 2021-06-05
    • 2018-05-17
    • 1970-01-01
    • 2013-06-28
    • 2019-03-10
    • 2010-09-09
    相关资源
    最近更新 更多