web-dev-qa-db-ja.com

java.lang.IllegalArgumentException:分離されたインスタンスの削除com.test.User#5

JPA(transaction-type = "JTA")をプロバイダーとして使用するJava EEプロジェクト。

EntityManagerDAOがあります:

@Stateful
public class EntityManagerDao implements Serializable {

    @PersistenceContext(unitName = "dtdJpa")
    private EntityManager entityManager;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public Object updateObject(Object object) {
        object = entityManager.merge(object);
        return object;
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void createObject(Object object) {
        entityManager.persist(object);
    }

    public void refresh(Object object) {
        entityManager.refresh(object);
    }

    public <T> T find(Class<T> clazz, Long id) {
        return entityManager.find(clazz, id);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void deleteObject(Object object) {
        entityManager.remove(object);
    }
}

しかし、deleteObjectを呼び出すと、この例外が発生します。

Java.lang.IllegalArgumentException:分離されたインスタンスの削除com.test.User#5

これはどのように引き起こされ、どうすれば解決できますか?

48
neptune

EntityManager#remove() は、現在のトランザクション/コンテキストで管理されているエンティティでのみ機能します。あなたの場合、以前のトランザクションでエンティティを取得し、HTTPセッションに保存してから、別のトランザクション/コンテキストで削除しようとしています。これは機能しません。

エンティティが EntityManager#contains() で管理されているかどうかを確認する必要があります。そうでない場合は、エンティティを管理します EntityManager#merge()

基本的に、ビジネスサービスクラスのdelete()メソッドは次のようになります。

em.remove(em.contains(entity) ? entity : em.merge(entity));
190
BalusC

私の場合、オブジェクトを削除しようとしたときに同じエラーが発生しました。

session.delete(obj)

その前にトランザクションを作成することなく。

そして、最初にトランザクションを作成し(session.beginTransaction())、次にオブジェクトを削除することで問題が解決します。

私の答えが誰かを助けることを願っています:)

3
Rajesh

単に、追加、削除、更新操作の@Transactionアノテーションが欠落しているためです。

0
Lingying Zhang

私は同じ問題に直面しました。切り離されたエンティティを再接続する必要があります。 @BalusCが述べたように、EntityManager.merge()を使用して、切り離されたエンティティをアタッチする必要があります。 EntityManager.merge()は、EntityManager.remove()を実行する必要があるエンティティの現在の状態を取得するSQLクエリを生成します。しかし、私の場合はうまくいきませんでした。代わりにEntityManager.remove(EntityManager.find(Class<T>,arg))を試してください。それは私のために働いた。

0
murali101002

私の経験では、DBからオブジェクトを照会し、エンティティマネージャーを閉じてからDB削除を行うと、問題が発生します。または、ロードしたオブジェクトを別のインスタンスにコピーしてから削除すると、この問題も発生します。私の意見では、注意すべき2つのことがあります:

  • オブジェクトは、Entity Managerによって作成された同じセッション内にある必要があります
  • また、Entity Managerのセッションがまだ開いている間は、オブジェクトを別のオブジェクトに転送しないでください。

乾杯

0
Artanis Zeratul