๋ชฉ์ฐจ
em.getReference() ๋ฉ์๋
@Entity
public class Member{
@Id @GeneratedValue
@Column(name="member_id")
private Long id;
private String name;
@ManyToOne
@JoinColumn(name="team_id")
private Team team;
private static void printMember(Member member){
System.out.println("member : " + member);
}
private static void printMemberAndTeam(Member member){
System.out.println("member : " + member);
System.out.println("team : " + member.getTeam());
}
}
@Entity
public class Team{
@Id @GeneratedValue
@Column(name="team_id")
private Long id;
private String name;
}
Member๋ฅผ DB์์ ์ฐพ์์์ ์ถ๋ ฅํ๋ค๊ณ ํ์.
Team์ ๋ด์ฉ์ ์ถ๋ ฅํ๋ค๋ฉด printMemberAndTeam()์ ์ฌ์ฉํด์ผํ๋ค.
Team์ ๋ด์ฉ์ ์ถ๋ ฅํ์ง ์๋๋ค๋ฉด printMember()๋ฅผ ์ฌ์ฉํด์ผํ๋ค.
printMember๋ฅผ ์ฌ์ฉํ ๋ JPA์์ Team์ ๋ด์ฉ์ ๊ฐ์ ธ์ค๋๋ฐ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด ์์์ ๋ญ๋น ์๋๊น?
์ด๋ด ๋ ์ฌ์ฉํ๋๊ฒ ํ๋ก์์ด๋ค.
JPA๋ DB์์ ์ค์ ์ํฐํฐ๋ฅผ ์กฐํํ๋ em.find()๋ฉ์๋์
์กฐํ๋ฅผ ์ต๋ํ ๋ฏธ๋ฃจ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ฐ์ง(ํ๋ก์) ์ํฐํฐ๋ฅผ ์กฐํํ๋ em.getReference()๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
em.getReference๋ DB์ ์ฟผ๋ฆฌ๊ฐ ์๋๊ฐ๋๋ฐ ์กฐํ๊ฐ ๋๋ ๊ฒ์ด๋ค.
Member member = new Member();
member.setName("hello");
em.persist(member);
em.flush();
//insert๋ฌธ ์ ์ก
em.clear();
Member findMember = em.getReference(Member.class, member.getId());
System.out.println("findMember : " + findMember.getClass());
//findMember : class hellojpa.Member$HibernateProxy$nMvq2opM
System.out.println("findMember.name : " + findMember.getName());
//select๋ฌธ ์ ์ก
//findMember.name : hello
getReference๋ฅผ ์ฌ์ฉํ๊ณ ํด๋์ค๋ฅผ ์กฐํํด๋ณด๋ฉด $HibernateProxy$~~ ๋ผ๋ ํด๋์ค๊ฐ ์กฐํ๋๋ค.
ํ๋ก์๋?
- ์ค์ ํด๋์ค๋ฅผ ์์๋ฐ์์ ๋ง๋ค์ด์ง๋ค.
- ์ค์ ๊ฐ์ฒด์ ์ฐธ์กฐ(target)์ ๋ณด๊ดํ๋ค.
- ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๋ฉด, ํ๋ก์๋ ์ค์ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
- ํ๋ก์ ๊ฐ์ฒด๋ ์ฒ์ ์ฌ์ฉํ ๋ ํ๋ฒ๋ง ์ด๊ธฐํ๋๋ค.
- ์ด๊ธฐํ๋ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ํตํด DB์์ ์กฐํ ํ ์ค์ ์ํฐํฐ๋ฅผ ์์ฑํ์ฌ ํ๋ก์์๊ฒ ์ฐ๊ฒฐํ๋ ์์ ์ด๋ค.
- ==๋น๊ต ๋์ instance of ๋ฅผ ์ฌ์ฉํด์ผํ๋ค.
- ํ๋ก์๊ฐ ์ด๊ธฐํ๋๋ค ํด๋ ์ค์ ์ํฐํฐ๋ก ๋ฐ๋๋ ๊ฒ์ ์๋๋ค. ํ๋ก์๋ฅผ ํตํด ์ํฐํฐ์ ์ ๊ทผํ๋ ๊ฒ์ด๋ค.
- ์์์ฑ ์ปจํ ์คํธ์ ์ฐพ๋ ์ํฐํฐ๊ฐ ์๋ค๋ฉด em.getReference()๋ฅผ ํธ์ถํด๋ ์ค์ ์ํฐํฐ ๋ฐํํ๋ค.
- ์์์ฑ ์ปจํ ์คํธ์ ๋์์ ๋ฐ์ ์ ์๋ ์ค์์ ์ํ์ผ ๋, ํ๋ก์๋ฅผ ์ด๊ธฐํํ๋ฉด LazyInitializationException ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
์ฆ์ ๋ก๋ฉ : FetchType.EAGER
printMemberAndTeam()์ฒ๋ผ Member์ Team์ด ์ฐ๊ฒฐ๋์ด์์๋
ํญ์ Member์ Team์ ์กฐ์ธํด์ ์กฐํํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ฃผ์!!
- ๊ฐ๊ธ์ ์ง์ฐ ๋ก๋ฉ๋ง ์ฌ์ฉํ์.
- ์ฆ์ ๋ก๋ฉ์ ์ ์ฉํ๋ฉด ์ฐ๊ด๊ด๊ณ์ ๋ชจ๋ ํ ์ด๋ธ์ ์กฐ์ธํด์ ๊ฐ์ ธ์ค๊ธฐ๋๋ฌธ์
Member๋ง ์ถ๋ ฅํ๋คํด๋ JPA์์๋ ๋ชจ๋ ํ ์ด๋ธ์ ์กฐํํ๋ค
- ์ฆ์๋ก๋ฉ์ JPQL์์ N+1๋ฌธ์ ๋ฅผ ์ผ์ผํจ๋ค.
select m from Member m ํ์ ๋, Member๋ฅผ ๊ฐ์ ธ์๋๋ Team์ด ์ฐ๊ฒฐ๋์ด์๋ค
์! Team๋ ์กฐํํด์ผํด! ํ๊ณ Team์ ์กฐํํ๋ ์ฟผ๋ฆฌ๋ฅผ ์ ์กํ๊ฒ๋๋ค. (Select๋ฌธ์ด 2๋ฒ ํธ์ถ๋จ)
์ง์ฐ ๋ก๋ฉ : FetchType.LAZY
printMember()์ฒ๋ผ Member์ Team์ด ์ฐ๊ฒฐ๋์ด์์ง๋ง
Member์ ๋ํ ๊ฒ๋ง ๋จผ์ ์กฐํํ๊ณ , Team์ ํ์ํ ๋๊ฐ ๋์ด์์ผ ์กฐํํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์์์ฑ ์ ์ด CASCADE
ํน์ ์ํฐํฐ๋ฅผ ์์์ํ๋ก ๋ง๋ค ๋, ์ฐ๊ด๋ ์ํฐํฐ๋ ํจ๊ป ์์์ํ๋ก ๋ง๋๋ ๊ฒ
๋ถ๋ชจ ์ํฐํฐ๋ฅผ ์ ์ฅํ ๋, ์์ ์ํฐํฐ๋ ํจ๊ป ์ ์ฅํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
cascade = CascadeType.PERSIST
๊ฒ์ํ - ์ฒจ๋ถํ์ผ ๊ด๊ณ์ฒ๋ผ "๊ฒ์ํ"์์๋ง "์ฒจ๋ถํ์ผ"์ ๊ด๋ฆฌํ ๋ ์ฌ์ฉํ๋ฉด ์ ์ฉํ๋ค.
์ฒจ๋ถํ์ผ์ ๋ค๋ฅธ ์ํฐํฐ์์๋ ๊ด์ฌํ๊ฒ๋๋ค๋ฉด, ์ฌ์ฉํ์ง ๋ง์
๊ณ ์๊ฐ์ฒด
๋ถ๋ชจ ์ํฐํฐ์ ์ฐ๊ด๊ด๊ณ๊ฐ ๋์ด์ง ์์ ์ํฐํฐ๋ฅผ ์๋์ผ๋ก ์ญ์ ํ๋ค.
orphanRemoval = true
parent.getChildList().remove(0) ํ๋ ๊ฒฝ์ฐ
์ญ์ ๋ child์ ๋ํด Delete์ฟผ๋ฆฌ๊ฐ ์ ์ก๋๋ค.