π± Entityμ μν (μλͺ μ£ΌκΈ°)
JPAμμ μν°ν°λ ν¬κ² 4κ°μ§ μνλ₯Ό κ°μ§λ€.
1. Transient (λΉμμ)
μν°ν° κ°μ²΄κ° Java λ©λͺ¨λ¦¬μμλ§ μ‘΄μ¬νκ³ , μμμ± μ»¨ν μ€νΈμ μ무 κ΄λ ¨ μλ μν
Person person = new Person();
2. Persistent (μμ)
μν°ν° κ°μ²΄κ° μμμ± μ»¨ν μ€νΈμ κ΄λ¦¬λ μν
μμ μνλΌκ³ λ°λ‘ λ°μ΄ν°λ² μ΄μ€μ μΏΌλ¦¬κ° λ λΌκ°λ κ²μ μλκ³ μ£Όλ‘ νΈλμμ μ΄ commit λκ±°λ flush λ©μλ μ€ν μ λ°μ΄ν°λ² μ΄μ€μ λ°μ λλ€.
entityManger.persist(person);
3. Detached (μ€μμ)
μν°ν° κ°μ²΄κ° μμμ± μ»¨ν μ€νΈμ μ μ₯λμλ€κ° λΆλ¦¬λ μν
λμ΄μ μμμ± μ»¨ν μ€νΈμ μν΄ κ΄λ¦¬λμ§ μκΈ° λλ¬Έμ 1μ°¨ μΊμ λ±μμ λͺ¨λ μ λ³΄κ° μμ λλ€.
entityManger.detach(person);
4. Removed (μμ )
μν°ν°λ₯Ό μμμ± μ»¨ν μ€νΈμ λ°μ΄ν°λ² μ΄μ€μμ μμ ν μν
entityManger.remove(person);
Cascade μ΅μ μ μ΄λ¬ν μν λ³νλ₯Ό μ°κ΄λ μν°ν°μ μ μ΄μν€λ μ΅μ μ΄λ€.
π± Cascade λ?
Cascadeλ JPA(Java Persistence API)μμ μ°κ΄κ΄κ³λ₯Ό κ°μ§ μν°ν°μ μλͺ μ£ΌκΈ°λ₯Ό κ΄λ¦¬νκΈ° μν΄ μ¬μ©λλ μ€μ μ΄λ€.
μ΄ μ΅μ μ μ€μ νλ©΄ λΆλͺ¨ μν°ν°μ μν λ³κ²½μ΄λ μμ κ° μμ μν°ν°μκ²λ μν₯μ λ―ΈμΉκ² λλ€.
리뷰(Review)μ 리뷰 μ΄λ―Έμ§(ReviewImage)λ₯Ό μμλ‘ λ€μ΄λ³΄λ©΄
@Entity
public class Review {
@Id
@GeneratedValue
private Long id;
private String content;
@OneToMany(mappedBy = "review")
private List<ReviewImage> reviewImages = new ArrayList<>();
// constructor, getter, setter, ...
}
@Entity
public class ReviewImage {
@Id
@GeneratedValue
private Long id;
private String imageUrl;
@ManyToOne
@JoinColumn(name = "review_id")
private Review review;
// constructor, getter, setter, ...
}
@Test
public void no_cascade() {
Review review = new Review();
review.setContent("리뷰 λ΄μ©");
ReviewImage reviewImage1 = new ReviewImage();
reviewImage1.setImageUrl("리뷰μ΄λ―Έμ§1 url");
ReviewImage reviewImage2 = new ReviewImage();
reviewImage2.setImageUrl("리뷰μ΄λ―Έμ§2 url");
review.getReviewImageList().add(reviewImage1);
review.getReviewImageList().add(reviewImage2);
// μμν μμ
μν
entityManager.persist(review);
entityManager.persist(reviewImage1);
entityManager.persist(reviewImage2);
}
Review μν°ν°μ ReviewImage μν°ν°λ μλ°©ν₯ μ°κ΄κ΄κ³κ° λ§Ίμ΄μ Έμλ€.
λ§μ§λ§ ν μ€νΈ μ½λμμ λ§λ [review, reviewImage1, reviewImage2] μΈ μΈμ€ν΄μ€λ₯Ό μμννκΈ° μν΄μλ entityManager.persist λ©μλλ₯Ό 3λ² νΈμΆν΄ Reviewμ ReviewImageλ₯Ό κ°κ° μμν μμΌμ£Όλ μμ μ μ§νν΄μΌ νλ€.
μ¬κΈ°μ Reviewκ³Ό κ΄λ¦¬νλ ReviewImage μΈμ€ν΄μ€μ κ²½μ° Reviewλ₯Ό persist νλ©΄ ReviewImage μλμΌλ‘ persist ν΄μ€ μ μλ μ΅μ μ΄ Cascadeμ΄λ€.
π± Cascade μ΅μ
- PERSIST
- MERGE
- REMOVE
- REFRESH
- DETATCH
- ALL
리뷰(Review)μ 리뷰 μ΄λ―Έμ§(ReviewImage)λ₯Ό μμλ‘ λ€μ΄λ³΄λ©΄
@Entity
public class Review {
@Id
@GeneratedValue
private Long id;
private String content;
@OneToMany(mappedBy = "review")
private List<ReviewImage> reviewImages = new ArrayList<>();
// constructor, getter, setter, ...
}
@Entity
public class ReviewImage {
@Id
@GeneratedValue
private Long id;
private String imageUrl;
@ManyToOne
@JoinColumn(name = "review_id")
private Review review;
// constructor, getter, setter, ...
}
𫧠CascadeType.PERSIST
νμ μν°ν°κΉμ§ μμμ±μ μ λ¬νλ€.
Review μν°ν°λ₯Ό μ μ₯νλ©΄ νμ μν°ν°μΈ ReviewImage μν°ν°λ μμμ± μ»¨ν μ€νΈμ μ μ₯νλ€.
@Test
public void persist_test() {
Review review = new Review();
review.setContent("리뷰 λ΄μ©");
ReviewImage reviewImage1 = new ReviewImage();
reviewImage1.setImageUrl("리뷰μ΄λ―Έμ§1 url");
ReviewImage reviewImage2 = new ReviewImage();
reviewImage2.setImageUrl("리뷰μ΄λ―Έμ§2 url");
review.getReviewImageList().add(reviewImage1);
review.getReviewImageList().add(reviewImage2);
// μμν μμ
μν
entityManager.persist(review);
entityManager.flush();
}
review μν°ν°λ₯Ό μμννλ©΄ PERSIST μ΅μ μΌλ‘ μΈν΄ [reviewImage1, reviewImage2]λ μμν λλ€.
𫧠CascadeType.MERGE
νμ μν°ν°κΉμ§ λ³ν© μμ μ μ§μνλ€.
Review μν°ν°μ ReviewImage μν°ν°λ₯Ό μ‘°νν΄μ μμ ν ν Review μν°ν°λ₯Ό Mergeνλ©΄ νμ μν°ν°μΈ ReviewImage μν°ν°μ λ³κ²½ μ¬νλ μμ λλ€.
@Test
public void merge_test() {
Review review = new Review();
review.setContent("리뷰 λ΄μ©");
ReviewImage reviewImage1 = new ReviewImage();
reviewImage1.setImageUrl("리뷰μ΄λ―Έμ§1 url");
ReviewImage reviewImage2 = new ReviewImage();
reviewImage2.setImageUrl("리뷰μ΄λ―Έμ§2 url");
review.getReviewImageList().add(reviewImage1);
review.getReviewImageList().add(reviewImage2);
// μμν μμ
μν λ° μμμ± μ»¨ν
μ€νΈ μ΄κΈ°ν
entityManager.persist(review);
entityManager.flush();
entityManager.clear();
Review savedReview = entityManager.find(0L, Review.class);
ReviewImage savedReviewImage = entityManager.find(0L, ReviewImage.class);
// μν°ν° μμ
savedReview.setContent("리뷰 λ΄μ© μμ ");
savedReviewImageUrl.setImageUrl("리뷰μ΄λ―Έμ§1 url μμ ");
// merge μμ
μν
entityManager.merge(savedReview);
entityManager.flush();
}
review μν°ν° merge μ MERGE μ΅μ μΌλ‘ μΈν΄ reviewImage1λ merge λλ€.
𫧠CascadeType.REMOVE
νμ μν°ν°κΉμ§ μμ μμ μ μ§μνλ€.
Review μν°ν°λ₯Ό μμ νλ©΄ νμ μν°ν°μΈ ReviewImage μν°ν°λ μμ λλ€.
@Test
public void remove_test() {
Review review = new Review();
review.setContent("리뷰 λ΄μ©");
ReviewImage reviewImage1 = new ReviewImage();
reviewImage1.setImageUrl("리뷰μ΄λ―Έμ§1 url");
ReviewImage reviewImage2 = new ReviewImage();
reviewImage2.setImageUrl("리뷰μ΄λ―Έμ§2 url");
review.getReviewImageList().add(reviewImage1);
review.getReviewImageList().add(reviewImage2);
// μμν μμ
μν λ° μμμ± μ»¨ν
μ€νΈ μ΄κΈ°ν
entityManager.persist(review);
entityManager.flush();
entityManager.clear();
Review savedReview = entityManager.find(0L, Review.class);
// remove μμ
μν
entityManager.remove(savedReview);
entityManager.flush();
}
review μν°ν° remove μ REMOVE μ΅μ μΌλ‘ μΈν΄ [reviewImage1, reviewImage2]λ remove λλ€.
𫧠CascadeType.REFRESH
μμλ μνμμ μ‘°νν μν°ν°κ° λ³κ²½λλλΌλ, refresh() ν΄μ λ°μ΄ν°λ² μ΄μ€μ μ μ₯λ κ°μ override νκ³ , μμ μν°ν°λ refresh νλ€.
→ μμμ± μ»¨ν μ€νΈμ μ μ₯λ κ° μλ‘κ³ μΉ¨
Review μν°ν°λ₯Ό Refreshνλ©΄ νμ μν°ν°μΈ ReviewImage μν°ν°λ Refreshλλ€.
𫧠CascadeType.DETACH
μμμ± μ»¨ν μ€νΈμμ λμ΄μ ν΄λΉ μν°ν°λ₯Ό κ΄λ¦¬νμ§ μλ μ€μμ μνλ‘ λ§λ λ€.
Review μν°ν°λ₯Ό Detachνλ©΄ νμ μν°ν°μΈ ReviewImage μν°ν°λ Detachλλ€.
𫧠CascadeType.ALL
μμ μ΅μ λ€μ΄ λͺ¨λ μ μ©λ μνλ‘, μμ μν°ν°μ λͺ¨λ μν λ³ν μμ μ΄ νμ μν°ν°μ μ νλλ€.
'Back-end' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[JPA] @SQLDeleteμ μμμ± μ»¨ν μ€νΈ (0) | 2024.04.22 |
---|---|
[JPA] CascadeType.REMOVE vs orphanRemoval = true (0) | 2024.04.21 |
[JPA] EntityManager ν΅μ¬ κΈ°λ₯ (0) | 2024.04.19 |
[Spring] Spring REST Docs κΆν μλ¬ (2) | 2024.02.29 |
[Spring] μμ‘΄μ± μ£Όμ μ @Autowiredλ³΄λ€ μμ±μ μ£Όμ μ κΆμ₯νλ μ΄μ (0) | 2024.02.28 |