๋ฐ์ํ
์๋ฐ ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ - ๊ธฐ๋ณธํธ์ ๊ณต๋ถํ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
์์์ฑ ์ ์ด : CASCADE
- ํน์ ์ํฐํฐ๋ฅผ ์์ ์ํ๋ก ๋ง๋ค ๋, ์ฐ๊ด๋ ์ํฐํฐ๋ ํจ๊ป ์์ ์ํ๋ก ๋ง๋ค๊ณ ์ถ์ ๋
: ๋ถ๋ชจ ์ํฐํฐ๋ฅผ ์ ์ฅํ ๋ ์์ ์ํฐํฐ๋ ํจ๊ป ์ ์ฅ. - ์ํฐํฐ๋ฅผ ์ ์ฅํ ๋, ์ฐ๊ด๋ ์ํฐํฐ๋ ํจ๊ป ์์ํํ๋ ํธ๋ฆฌํจ์ ์ ๊ณตํจ
- CASCADE ์ ์ข
๋ฅ
- - ALL : ๋ชจ๋ ์ ์ฉ (๋ถ๋ชจ lifeCycle์ ๋ง์ถฐ์ผ ํ ๋)
- ALL์ ์ฌ์ฉํ๊ธฐ ์ํ ์กฐ๊ฑด 2๊ฐ์ง
- parent์ child์ lifeCycle์ด ์ ์ฌํ ๋! ( ๋ฑ๋ก, ์์ ์ญ์ ์์ ์ด ๊ฐ์ ๊ฒฝ์ฐ)
- ๋จ์ผ ์์ ์ ์ผ๋! (parent๋ง child๋ฅผ ์์ ํ ๋)
- ALL์ ์ฌ์ฉํ๊ธฐ ์ํ ์กฐ๊ฑด 2๊ฐ์ง
- - PERSIST : ์์ (์ ์ฅํ ๋๋ง ๋ง์ถฐ์ผ ํ ๋)
- - REMOVE : ์ญ์
- - ALL : ๋ชจ๋ ์ ์ฉ (๋ถ๋ชจ lifeCycle์ ๋ง์ถฐ์ผ ํ ๋)
CASCADE : PERSIST
@OneToMany(mappedBy = "parent" , cascade = CascadeType.PERSIST)
private List<Child> childList = new ArrayList<>();
์ด๋ ๊ฒ ํด์ฃผ๋ฉด parent๋ฅผ persist๋ฅผ ํ ๊ฒฝ์ฐ์, parent์ ์๋ child๊น์ง persist๊ฐ ์ ์ด๊ฐ ๋๋ค.
Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);
em.persist(parent); // -> CASCADE์ต์
๋์ em.persist(child1) + em.persist(child2) ๊น์ง ๋ ์
์ด๋ค.
๊ณ ์ ๊ฐ์ฒด(orphanRemoval)
- ๊ณ ์ ๊ฐ์ฒด ์ ๊ฑฐ : ๋ถ๋ชจ ์ํฐํฐ์ ์ฐ๊ด๊ด๊ณ๊ฐ ๋์ด์ง ์์ ์ํฐํฐ๋ฅผ ์๋์ผ๋ก ์ญ์
- @OneToOne , @OneToMany๋ง ๊ฐ๋ฅ
- ๋ถ๋ชจ๋ฅผ ์ ๊ฑฐํ ๋ ์์๋ ํจ๊ป ์ ๊ฑฐ! ( CascadeType.REMOVE ์ ์ ์ฌํ๋ค.)
- ์ฐธ์กฐํ๋ ๊ณณ์ด ํ๋์ผ ๋ ์ฌ์ฉํด์ผ ํจ!
- ํน์ ์ํฐํฐ๊ฐ ๊ฐ์ธ ์์ ํ ๋ ์ฌ์ฉ
@Entity
public class Parent {
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanremoval = true)
private List<Child> childList = new ArrayList<>();
...
// ํธ์ ๋ฉ์๋ ์ ์
public void addChild(Child child) {
childList.add(child);
child.setParent(this);
}
}
public static void main(String[] args) {
// ์ ๋ถ๋ถ ์๋ต...
Child child = new Child();
Parent parent = new Parent();
parent.addChild(child);
em.persist(parent); // cascade๋ก ์ธํด childํจ๊ป persist.
em.flush();
em.close();
Parent findParent = em.find(Parent.class , parent.getId());
findParent.getChildList().remove(0); // ์๋๋ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ์๋ parent์์ child๋ฅผ ์ญ์ ์ํค๋๊ฒ ๋ถ๊ฐ๋ฅ ํ๋ค. ํ์ง๋ง cascade ์ต์
๊ณผ, orphanremoval๋ก ์ธํด ์ฃผ์ธ์ด ์๋ parent์์๋ ์ญ์ ๊ฐ ๊ฐ๋ฅํ๊ฒ ๋ ๊ฒ์ด๋ค.
// em.remove(findParent); ์ด๋ ๊ฒ parent ์์ฒด๋ฅผ ์ญ์ ์์ผ๋ orphanRemoval๊ฐ ์๋ํ๋ค!
}
์์์ฑ ์ ์ด + ๊ณ ์ ๊ฐ์ฒด, ์๋ช ์ฃผ๊ธฐ
cascade = CascadeType.ALL + orphanRemoval = true
- ๋ ์ต์ ์ ๋ชจ๋ ํ์ฑํ ํ๋ฉด -> ๋ถ๋ชจ ์ํฐํฐ๋ฅผ ํตํด์ ์์์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ค.
- ์ค์ค๋ก ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๋ ์ํฐํฐ๋ em.persist()๋ก ์์ํ, em.remove()๋ก ์ ๊ฑฐ
์ด๋ ๊ฒ ๋๋ฉด, ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ์๋ Parent์์ ์์ ์ํฐํฐ(Child)์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌ ํ ์ ์๋ค.
- CascadeType.ALL
- em.persist(parent) -> ์์ ์ํฐํฐ ํจ๊ป ์ ์ฅ : em.persist(child)
- em.remove(parent) -> ์์ ์ํฐํฐ ํจ๊ป ์ญ์ : em.remove(child)
- orphanRemoval = true
- findParent.getChileList().remove(0) -> ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ด ์๋๋๋ผ๋, ์์ ์ํฐํฐ ์ญ์ ๊ฐ๋ฅ
๋ฐ์ํ