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

このエラーは、コード内の競合状態が原因である可能性があります。2 つ以上のスレッドが同じキーで Hello エンティティを更新しようとしている場合、両方のスレッドがnullfind から返される可能性があり、エンティティを永続化しようとします。その結果、「最速」のスレッドのみが成功し、他のスレッドは制約違反に遭遇します。

value.getKey()が Hello エンティティの主キーである場合、実行するだけmerge(...)で十分です。Hibernate は、エンティティがデータベースまたはキャッシュに既に存在するかどうかを確認し、それに応じて INSERT または UPDATE を実行します。ただし、同時実行では予期しない結果が生じる可能性があります (順不同の更新と見なされます)。

Hello エンティティの主キーでない場合は、この回答が役立つ可能性があります。

于 2013-07-11T16:51:07.797 に答える