違いは何ですか
@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }
そして
@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }
この例はJava EEチュートリアルからのものですが、詳細はまだわかりません。
違いは何ですか
@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }
そして
@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }
この例はJava EEチュートリアルからのものですが、詳細はまだわかりません。
回答:
ここから:-
カスケード削除
CascadeType.REMOVE(またはREMOVEを含むCascadeType.ALL)で参照フィールドをマークすると、そのフィールドによって参照されるエンティティオブジェクトに削除操作が自動的にカスケードされることを示します(コレクションフィールドによって複数のエンティティオブジェクトを参照できます)。
@Entity class Employee { : @OneToOne(cascade=CascadeType.REMOVE) private Address address; : }
孤立した削除
JPA 2は、@ OneToOneおよび@OneToManyアノテーションのorphanRemoval要素を使用して指定できる追加のより積極的な削除カスケードモードをサポートしています。
@Entity class Employee { : @OneToOne(orphanRemoval=true) private Address address; : }
差:-
2つの設定の違いは、関係の切断への応答にあります。たとえば、住所フィールドをnullまたは別のAddressオブジェクトに設定する場合などです。
- 場合orphanRemoval =真 ISは、指定された切断Addressインスタンスは自動的に削除されます。これは、所有者オブジェクト(従業員など)からの参照なしでは存在してはならない依存オブジェクト(住所など)をクリーンアップするのに役立ちます。
- cascade = CascadeType.REMOVEのみが指定されている場合、関係の切断は削除
操作ではないため、自動アクションは実行されません。
違いを理解するための簡単な方法CascadeType.REMOVE
とはorphanRemoval=true
。
孤立した削除の場合:を呼び出すsetOrders(null)
と、関連するOrder
エンティティがdbから自動的に削除されます。
カスケードの削除の場合:を呼び出したsetOrders(null)
場合、関連するOrder
エンティティはdbから自動的に削除されません。
子エンティティと親エンティティがあるとします。親は複数の子供を持つことができます。
@Entity
class parent {
//id and other fields
@OneToMany (orphanRemoval = "true",cascade = CascadeType.REMOVE)
Set<Person> myChildern;
}
orphanRemovalはORMの概念であり、子が孤立しているかどうかを示します。また、データベースからも削除する必要があります。
親からアクセスできない場合、子は孤立します。たとえば、Personオブジェクトセットを削除する(空のセットに設定する)か、または新しいセットに置き換えると、親は古いセットの子にアクセスできなくなり、子は孤立し、子は運命づけられますデータベースからも削除されました。
CascadeType.REMOVEはデータベースレベルの概念であり、親が削除されたかどうかを通知し、子テーブル内の関連するすべてのレコードを削除する必要があります。
実際の違いは、データを更新しようとしているのか(PATCH)、データ全体を置き換えようとしているのか(PUT)です。
あなたが削除しましょうcustomer
使用するよりcascade=REMOVE
も、意図と便利なように見えるその顧客の注文を削除します。
@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }
ここで、を更新するcustomer
とorphanRemoval="true"
、以前のすべての注文が削除され、提供された注文に置き換えられます。(PUT
に関してREST API
)
@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }
orphanRemoval
古い注文がなければ維持されます。(PATCH
に関してREST API
)
この質問は非常に一般的であるため、この回答は私がブログに書いたこの記事に基づいています。
CascadeType.REMOVE
あなたが明示的に設定することができます戦略:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.REMOVE
)
private List<PostComment> comments = new ArrayList<>();
またはCascadeType.ALL
戦略から暗黙的に継承します:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL
)
private List<PostComment> comments = new ArrayList<>();
remove
親エンティティから子エンティティに操作を伝播できます。
したがって、親Post
エンティティとそのcomments
コレクションをフェッチし、エンティティを削除すると、次のようになりpost
ます。
Post post = entityManager.createQuery("""
select p
from Post p
join fetch p.comments
where p.id = :id
""", Post.class)
.setParameter("id", postId)
.getSingleResult();
entityManager.remove(post);
Hibernateは3つの削除ステートメントを実行します。
DELETE FROM post_comment
WHERE id = 2
DELETE FROM post_comment
WHERE id = 3
DELETE FROM post
WHERE id = 1
PostComment
子エンティティがあるため、削除されたCascadeType.REMOVE
私たちは、同様の子実体を削除かのように行動した戦略、。
孤児除去戦略。これは、orphanRemoval
属性を介して設定する必要があります。
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
コレクションから子エンティティを削除するときに、子テーブル行を削除できます。
したがって、Post
エンティティをそのcomments
コレクションとともにロードし、最初のエンティティをコレクションから削除すると、次のようPostComment
になりcomments
ます。
Post post = entityManager.createQuery("""
select p
from Post p
join fetch p.comments c
where p.id = :id
order by p.id, c.id
""", Post.class)
.setParameter("id", postId)
.getSingleResult();
post.remove(post.getComments().get(0));
Hibernateは関連するpost_comment
テーブル行に対してDELETEステートメントを実行します:
DELETE FROM post_comment
WHERE id = 2
このトピックの詳細については、こちらの記事もご覧ください。