2

それぞれ双方向の 1 対多の関係にある2 つのエンティティ クラスABがあります。

A.java:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "aId",
           fetch=FetchType.EAGER, orphanRemoval=true)
private Set<B> bCollection = new LinkedHashSet<B>();

B.java

  @JoinColumn(name = "A_ID", referencedColumnName = "ID", nullable=false)
  @ManyToOne(optional = false)   
  private A aId;

単純なコンソール アプリケーションでは、データベースから特定の A行を取得し、その詳細B行の 1 つを (ランダムに) 削除しようとしますが、JPA/Hibernateは行を削除するだけでなく、その行に対してDELETEステートメントを発行することさえしません。データベース。B行を削除する唯一の方法は、対応するエンティティをA.javaのコレクション ( LinkedHashSet )から削除することです。したがって、回避策はありますが、以下のコードが失敗する理由と、静かに失敗する理由を理解したいと思います!

public static void main(String[] args) {
    EntityManagerFactory entityManagerFactory =  Persistence.createEntityManagerFactory("testjpa");
    EntityManager em = entityManagerFactory.createEntityManager();
    EntityTransaction entityTransaction = em.getTransaction();
    entityTransaction.begin();
    A a = em.find(A.class, 1);
    B b = getARandomChildOfA(a);
    em.remove(em.merge(b));     // simple em.remove(b) doesn't work either
    entityTransaction.commit();
    em.close();
    entityManagerFactory.close();
}
4

1 に答える 1

6

JPA はリレーションを管理しないため、b で remove を呼び出しても、a にはまだそれへの参照があります。参照にはカスケードの永続化/マージが設定されているため、コンテキストで b が復活し、削除が元に戻されます。

モデルをデータベースに必要なものと同期させるには、参照を維持する必要があります。このような潜在的な不整合に対処できることが確実でない限り、削除するオブジェクトへの参照を無効にし、ポインターを元に戻すことをお勧めします。

于 2012-10-30T21:54:46.593 に答える