[PJT/JPAを選択]JPAの外部キー整合性/CAdidate Entityが双方向マッピングを放棄した理由
15921 ワード
1.双方向マッピングを試みる理由
2.双方向マッピングを放棄した理由
1つ目のアイデア:idクエリを使用して削除するCandidateを検索する場合は、関連エンティティ(sns、youtube)をfetchで結合する必要があります.cascadeがうまく適用されるのではないでしょうか.
だからjoin fetchクエリーを書いたとき、金英漢の基礎授業で聞いた内容を思い出した.
複数のテーブル間を結合してエンティティの形状とまったく異なる結果を生成する必要がある場合は、ペアリング結合ではなく通常の結合を使用し、必要なデータのみを問合せてDTOに戻るのが有効です.
したがって,双方向マッピングを再利用する理由はない.
3.参照整合性の確保方法
現在のSns、YoutubeエンティティはCandidateに関連付けられているため、Spring Bootを起動すると次のクエリが失われます.
CandidateはCascadeとして管理されなくなったため、レポート候補となります.remove(候補)を試してみると、次のエラーが発生します.
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["FKDGYKRP9VG5PBS7S05I53938T2: PUBLIC.SNS FOREIGN KEY(CANDIDATE_ID) REFERENCES PUBLIC.CANDIDATE(CANDIDATE_ID) (2)"; SQL statement:
delete from candidate where candidate_id=? [23503-200]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
これは、外部キーの整合性の要件に違反しているため、クエリ自体が実行できないことを意味します.当たり前のことです.スプリングは外部キーの整合性を管理しないためです.したがって、この場合、データベースは外部キーの整合性を管理するために設定を変更する必要があります.
SQLはデータベースをON DELETE CASCADEに設定しますが、Spring Bootを使用してテーブルを作成するため、SnsおよびYoutubeエンティティに次の項目を追加する必要があります.
@OnDelete(action = OnDeleteAction.CASCADE)
public class Youtube {
@Id @GeneratedValue
@Column(name = "youtube_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "candidate_id")
@OnDelete(action = OnDeleteAction.CASCADE) //여기에 추가해 주시면 됩니다.
private Candidate candidate;
...
}
そうすると、alterクエリにondeleteカスケードが追加されます.@Inheritance(strateg=InheritanceType.JOINED)に設定されているエンティティの場合:
@Entity
@DiscriminatorValue("F")
@OnDelete(action = OnDeleteAction.CASCADE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Facebook extends Sns{
private int likes;
private int comments;
private int shares;
これでいい4.変更されたコード
Candidate Entity
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Candidate {
@Id @GeneratedValue
@Column(name = "candidate_id")
private Long id;
private int number;
@Column(name = "candidate_name")
private String name;
@Column(name = "candidate_likes")
private int likes;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "city_id")
private City city;
@Builder
public Candidate(int number, String name, City city) {
this.number = number;
this.name = name;
this.likes = 0;
this.city = city;
}
}
削除Candidate Service
5.Candidateエンティティを変更してテストする
テストコード
@Test
public void 후보_삭제_ON_DELETE_CASCADE() throws Exception {
//given
City city = createCity();
Candidate candidate = new Candidate(1, "Jake", city);
candidateRepository.save(candidate);
Facebook facebook = new Facebook(candidate, "content1", "url", LocalDateTime.now(), 1, 1, 1);
facebookRepository.save(facebook);
Youtube youtube = new Youtube(candidate, "url", "title", "thumbnail", LocalDateTime.now(), "description", 1, 1, LocalDateTime.now());
youtubeRepository.save(youtube);
//when
Long candidateId = candidate.getId();
candidateService.delete(candidateId);
//then
assertEquals(0, snsRepository.findAllByCandidateId(candidateId).size());
assertEquals(0, youtubeRepository.findAllByCandidateId(candidateId).size());
}
テスト結果
Reference
この問題について([PJT/JPAを選択]JPAの外部キー整合性/CAdidate Entityが双方向マッピングを放棄した理由), 我々は、より多くの情報をここで見つけました https://velog.io/@mincho920/ElectionPJTJPA-JPA의-외래-키-무결성-Candidate-Entity에서-양방향-매핑을-포기한-이유テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol