1

さらに別の多対多のHibernateの質問。私は次のように可能な限り単純な多対多のマッピングを持っています:

@Entity
public class Strategy implements Serializable {
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "STRATEGY_TO_GROUP", joinColumns = {@JoinColumn(name="STRATEGY_ID")}, inverseJoinColumns = {@JoinColumn(name = "STRATEGY_GROUP_ID")})
    private Set<StrategyGroup> groups;
...
}

そして、関係の反対側は次のとおりです。

@Entity
public class StrategyGroup implements Serializable {

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "STRATEGY_TO_GROUP", joinColumns = {@JoinColumn(name="STRATEGY_GROUP_ID")}, inverseJoinColumns = {@JoinColumn(name = "STRATEGY_ID")})
    private Set<Strategy> strategies = new HashSet<Strategy>();

私が今やりたいのは、可能な限り最も簡単な方法で両方のテーブルを空にすることです。私はフォローしようとしています(emは私のentityManagerです)。

em.createQuery("delete from StrategyGroup sg").executeUpdate();
em.createQuery("delete from Strategy s").executeUpdate();

これにより、@joinTableの制約違反が発生します。一方、em.remove(strategyGroup);tiで削除すると正常に機能します。戦略グループが削除され、@joinTableが正しく更新されます。

では、どうすればテーブルを空にできますか?オブジェクトをロードして1つずつ削除する必要がありますか?

手伝ってくれてありがとう。

4

1 に答える 1

3

まず、マッピングが間違っています。アソシエーションの片側は所有者側である必要があり、アソシエーションのマッピングを定義します。もう一方は挿入側である必要があり、mappedBy 属性を使用するだけです。

@ManyToMany(fetch = FetchType.EAGER, mappedBy = "groups")
private Set<Strategy> strategies = new HashSet<Strategy>();

次に、toMany アソシエーション、特に両側での EAGER フェッチを避ける必要があります。これにより、Hibernate は関連付けられたすべてのエンティティを再帰的にロードし、ロードするたびに両方のテーブルのすべての行をメモリにロードする可能性が高くなります。一列。

今あなたの質問に:

両方のテーブルからすべてを削除する場合は、最初に結合テーブルが空であることを確認する必要があります。そうしないと、テーブルの 1 つの行が結合テーブルの行によって参照されたままになり、明らかに失敗します。これを行うには、SQL クエリを使用して結合テーブルからすべてを削除してから、既にある 2 つの HQL クエリを実行するのが最善の方法です。

于 2012-06-22T09:16:43.277 に答える