1

我在多线程程序中运行以下代码并得到异常:-

org.hibernate.exception.ConstraintViolationException:错误:重复键值违反唯一约束“value_pkey”

    @Stateless
    @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)
    public class GetHelloBean{
    @PersistenceContext(unitName = "test-unit")
        private EntityManager entityManager;

    public Hello<?> insertOrUpdateHello(Hello<?> value) {
        Hello<?> existing = null;
        try {
             existing = this.entityManager.find(Hello.class,
                    value.getKey());
            if (existing != null) {
                value = this.entityManager.merge(value);
            } else {
                this.entityManager.persist(value);
            }
            this.entityManager.flush();
        } catch (Exception e) {
            this.logger.error(" value not saved : " + value.toString()
                    + " of class  " + value.getClass() + ":" + e.getMessage());
        }

        //      

        return value;
    }

}

有人可以解释为什么以及我该如何处理吗?

4

1 回答 1

0

此错误可能是由代码中的竞争条件引起的。如果两个或多个线程尝试使用相同的键更新 Hello 实体,它们可能都会null从 find 返回并尝试持久化实体。因此,只有“最快”的线程会成功,而其他线程会遇到约束违规。

如果value.getKey()是 Hello 实体的主键,只做 amerge(...)就足够了。Hibernate 将检查实体是否已经存在于数据库或缓存中,并根据该实体执行 INSERT 或 UPDATE。不过,并发执行可能仍会产生意外结果(感知到无序更新)。

如果它不是 Hello 实体的主键,也许这个答案可以帮助你。

于 2013-07-11T16:51:07.797 回答