@ManyToOne JPAアソシエーションのCascadeType.ALLの意味は何ですか


210

@ManyToOne関係の文脈でカスケードすることの意味を誤解したと思います。

ケース:

public class User {

   @OneToMany(fetch = FetchType.EAGER)
   protected Set<Address> userAddresses;

}

public class Address {

   @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   protected User addressOwner;

}

の意味は何cascade = CascadeType.ALLですか?たとえば、データベースから特定のアドレスを削除した場合、追加した事実がデータにどのようにcascade = CascadeType.ALL影響しますか(Userたぶん)。

回答:


360

の意味CascadeType.ALLは、永続性がすべてのEntityManager操作(PERSIST, REMOVE, REFRESH, MERGE, DETACH)を関連エンティティに伝播(カスケード)することです。

Addressを削除すると関連するが削除されるため、あなたの場合は悪い考えUserです。ユーザーは複数のアドレスを持つことができるため、他のアドレスは孤立します。ただし、逆のケース(に注釈を付けるUser)は理にかなっています。アドレスが単一のユーザーにのみ属している場合、このユーザーが削除されたときに、ユーザーに属するすべてのアドレスの削除を伝播しても安全です。

ところで、結合列がADDRESSテーブルにある必要があることを永続化プロバイダーに通知するmappedBy="addressOwner"属性をに追加することができUserます。


55
+1は、私がこれまでに遭遇したmapedByの最良かつ最短の説明です。
Ridcully 2014

4
ただし、@ OneToMany側にCascadeType.ALLがあるとよいでしょう。
mvmn 2017年

48

OpenJPAのドキュメントの例については、こちらご覧くださいCascadeType.ALLすべてのアクションを実行することを意味します。

見積もり:

CascadeType.PERSIST:エンティティを永続化するとき、そのフィールドに保持されているエンティティも永続化します。EntityManagerがフラッシュ中に新しいエンティティを参照するフィールドを見つけ、そのフィールドがCascadeType.PERSISTを使用しない場合、エラーになるため、このカスケードルールの自由な適用をお勧めします。

CascadeType.REMOVE:エンティティを削除すると、このフィールドに保持されているエンティティも削除されます。

CascadeType.REFRESH:エンティティを更新するときに、このフィールドに保持されているエンティティも更新します。

CascadeType.MERGE:エンティティの状態をマージするときに、このフィールドに保持されているエンティティもマージします。

セバスチャン


4
JPAの新機能であるこの情報は役に立ちますが、ここではデタッチについてはどうですか
Sarz 2014

1
CascadeType.DETACHでは、エンティティをアタッチ解除するときに、emは親エンティティによって保持されているエンティティもアタッチ解除します。
Dorian Mejer 16年

29

この記事と私の著書「High-Performance Java Persistence」で説明したようCascadeType.ALL@ManyToOneエンティティーの状態遷移は親エンティティーから子エンティティーに伝搬し、その逆は伝搬しないため、onを使用しないでください。

@ManyToOneそれが基礎となる外部キー列をマップするため、側面には、常に子供の団体です。

したがって、あなたが移動しなければならないCascadeType.ALLから@ManyToOneとの関連@OneToManyも使用する必要があります側、mappedByそれはだから属性を最も効率的な1対多のテーブルのリレーションシップ・マッピング


18

EJB3.0仕様から

カスケードアノテーション要素の使用は、関連付けられたエンティティに操作の効果を伝播するために使用できます。カスケード機能は、親子関係で最も一般的に使用されます。

Xが管理対象エンティティである場合、削除操作によりXが削除されます。Xからこれらの他のエンティティへの関係にcascade = REMOVEまたはcascade = ALLアノテーション要素値で注釈が付けられている場合、削除操作はXによって参照されるエンティティにカスケードされます。

したがって、簡単に言えば、で定義されたエンティティの関係CascadeType.Allにより、親で発生する永続化、更新、マージ、削除などのすべての永続化イベントが確実に子に渡されます。他のCascadeTypeオプションを定義すると、開発者はエンティティの関連付けが永続性を処理する方法をより詳細に制御できます。

たとえば、ページのリストを含むオブジェクトBookがあり、このリスト内にページオブジェクトを追加したとします。場合@OneToManyブックとページ間の関連付けを定義する注釈は次のようにマークされCascadeType.All、ブックを永続化することも、データベースに永続化されたページにつながります。


11

JPA 2.0では、ユーザーエンティティからアドレスを削除した場合にアドレスを削除したい場合は、のorphanRemoval=true代わりにに追加できCascadeType.REMOVEます@OneToMany

orphanRemoval=trueとの間の詳しい説明CascadeType.REMOVEこちらです。


4

ユーザーに割り当てられたアドレスを削除したいだけで、Userエンティティークラスに影響を与えたくない場合は、次のようなことを試してください。

@Entity
public class User {
   @OneToMany(mappedBy = "addressOwner", cascade = CascadeType.ALL)
   protected Set<Address> userAddresses = new HashSet<>();
}

@Entity 
public class Addresses {
   @ManyToOne(cascade = CascadeType.REFRESH) @JoinColumn(name = "user_id")
   protected User addressOwner;
}

これにより、アノテーションでフェッチを使用することを心配する必要がなくなります。ただし、ユーザーを削除するときは、ユーザーオブジェクトへの接続アドレスも削除することに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.