[JPA] ํ๋ก์(Proxy)์ ์ง์ฐ๋ก๋ฉ(Lazy Loading)
by rlaehddnd0422์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ๋ ์ฌ๋ฌ ์ํฐํฐ๊ฐ ์์ ๋ ํ ์ํฐํฐ๋ฅผ ์กฐํํ ๋ ๋ฐ๋์ ์ฐ๊ด๋ ์ํฐํฐ๋ค์ด ์ฌ์ฉ๋์ง๋ ์์ต๋๋ค.
๋ณธ๋ก ๋ถํฐ ๋งํ์๋ฉด, ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ๋ฉด Member์ํฐํฐ์ Team ์ํฐํฐ๊ฐ ๋ค๋์ผ๋ก ๋งคํ๋์ด ์์ ๋, Member Entity๋ฅผ ์กฐํํ๋ค๊ณ ํด์ ๋ฐ๋์ Team Entity๊น์ง ์กฐํ๋์ง ์์ต๋๋ค.
JPA๋ ์ํฐํฐ๊ฐ ์ค์ ์ฌ์ฉ๋ ๋๊น์ง ๋ฐ์ดํฐ๋ฒ ์ด์ค ์กฐํ๋ฅผ ์ง์ฐํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ์ง์ฐ ๋ก๋ฉ(Lazy Loading)์ด
๋ผ๊ณ ํฉ๋๋ค.
- ์ฝ๊ฒ ๋งํด team.getName() ์ฒ๋ผ Team ์ํฐํฐ์ ๊ฐ์ ์ค์ ์ฌ์ฉํ๋ ์์ ์ Team Entity์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์กฐํํฉ๋๋ค.
- ์ง์ฐ ๋ก๋ฉ ๊ธฐ๋ฅ์ ์ค์ ์ํฐํฐ ๊ฐ์ฒด ๋์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์กฐํ๋ฅผ ์ง์ฐํ ์ ์๋ ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํ๋ก์์ ๋ํด ์์๋ด ์๋ค.
ํ๋ก์
์ํฐํฐ๋ฅผ ์ค์ ์ฌ์ฉํ๋ ์์ ๊น์ง ๋ฐ์ดํฐ๋ฒ ์ด์ค ์กฐํ๋ฅผ ๋ฏธ๋ฃจ๊ณ ์ถ์ ๊ฒฝ์ฐ EntityManager.getReference()๋ฅผ ์ฌ์ฉํด์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
Member member = em.getReference(Member.class,1L);
- member๋ ์ค์ ๊ฐ์ฒด๊ฐ ์๋ ํ๋ก์ ๊ฐ์ฒด์ ๋๋ค.
- find() ๋ฉ์๋์ ๋ฌ๋ฆฌ ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ JPA๋ ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์กฐํํ์ง๋, ์ค์ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ์์์ฑ ์ปจํ ์คํธ์ ์์ํ์ง๋ ์์ต๋๋ค.
- ๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ์ ์์ํ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.
์กฐ๊ธ ํท๊ฐ๋ฆฌ๋๊น ํ๋ฆ์ ํ ๋ฒ ์ง๊ณ ๋์ด๊ฐ๊ฒ ์ต๋๋ค.
Member member = em.getReference(Member.class, 1L);
โก๏ธ Member ํ์ Proxy ๊ฐ์ฒด ์์ฑ (member)
// ํ๋ก์ ๊ฐ์ฒด ์ต์ด ์ฌ์ฉ -> ํ๋ก์ ๊ฐ์ฒด ์ด๊ธฐํ ์์ฒญ
member.getName();
// ์๋ณ์์ ๊ฒฝ์ฐ ์ด๊ธฐํ๋ฅผ ์์ฒญํ์ง ์์ต๋๋ค. ๋ค์์ ์ค๋ช
member.getId();
ํ๋ก์ ๊ฐ์ฒด๋ก ์ค์ ์ํฐํฐ ๊ฐ์ฒด์ ๋ฉ์๋ ํธ์ถ
โก๏ธ ์์์ฑ ์ปจํ ์คํธ์๊ฒ ์ค์ ์ํฐํฐ๋ฅผ ์์ฒญํฉ๋๋ค. (์ด๊ธฐํ ์์ฒญ)
โก๏ธ ์์์ฑ ์ปจํ ์คํธ์ ์๋ ๊ฒฝ์ฐ, ์์์ฑ ์ปจํ ์คํธ๋ DB๋ฅผ ์กฐํํ์ง ์๊ณ ํ๋ก์๊ฐ ์๋ ์์์ฑ ์ปจํ ์คํธ์ ์ค์ Entity๋ฅผ ๋ฐํํฉ๋๋ค. (์ค์ Entity ์ฌ์ฉ)
์กฐํ ๋์์ด ์์์ฑ ์ปจํ ์คํธ์ ์ด๋ฏธ ์์ผ๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ด์ ๊ฐ ์์ผ๋ฏ๋ก ์ค์ ์ํฐํฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
โก๏ธ ์์์ฑ ์ปจํ ์คํธ์ ์๋ ๊ฒฝ์ฐ, ์์์ฑ ์ปจํ ์คํธ๋ DB๋ฅผ ์กฐํํด์ ์ค์ Entity๋ฅผ ํ๋ก์ ๊ฐ์ฒด์ target์ ๋ฆฌํดํฉ๋๋ค. (์ค์ ์ํฐํฐ ์์ฑ ๋ฐ ์ฐธ์กฐ๋ฅผ ํ๋ก์์ ๋ณด๊ด)
โก๏ธ target์ getId()๋ฅผ ํธ์ถํด์ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํฉ๋๋ค. ( target.getId() ํธ์ถ ) (ํ๋ก์ ๊ฐ์ฒด์ ๋ฉ์๋ ์คํ -> ์ค์ ๊ฐ์ฒด์ ๋ฉ์๋ ์คํ)
ํ๋ก์์ ํน์ง
ํ๋ก์ ํด๋์ค๋ ์ค์ ํด๋์ค๋ฅผ ์์๋ฐ์ ๋ง๋ค์ด์ง๋ฏ๋ก ์ค์ ํด๋์ค์ ๊ฒ๋ชจ์์ด ๊ฐ์ต๋๋ค. ์ฌ์ฉ์๋ ์ด ๊ฐ์ฒด๊ฐ ํ๋ก์ ๊ฐ์ฒธ์ง, ์ค์ ์ํฐํฐ ๊ฐ์ฒด์ธ์ง ๊ตฌ๋ถํ์ง ์์๋ ๋ด๋ถ์ ์ผ๋ก ํ๋ก์๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๊ตฌ๋ถํ ํ์๊ฐ ์์ต๋๋ค.
- ํ๋ก์ ๊ฐ์ฒด๋ ์ฒ์ ์์ฑ์ ํ ๋ฒ๋ง ์ด๊ธฐํ๋ฉ๋๋ค.
- ํ๋ก์ ๊ฐ์ฒด๊ฐ ์ด๊ธฐํ ๋๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํตํด (์๋ฐํ ๋งํ๋ฉด ๋ด๋ถ์ ์ค์ ์ํฐํฐ์ ๋งคํ๋ target์ ํตํด) ์ค์ ์ํฐํฐ์ ์ ๊ทผํ ์ ์์ต๋๋ค.
- ์์์ฑ ์ปจํ ์คํธ์ ๋์์ ๋ฐ์์ผ ๊ฐ๋ฅํ๋ฏ๋ก ์ค์์ ์ํ์ ์ํฐํฐ๋ฅผ ํ๋ก์ ๊ฐ์ฒด๋ก ์์ฑํ ๊ฒฝ์ฐ, ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
ํ๋ก์์ ์๋ณ์(PK)
์ํฐํฐ๋ฅผ ํ๋ก์๋ก ์กฐํํ ๋ ์๋ณ์(PK) ๊ฐ์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํ๋๋ฐ ํ๋ก์ ๊ฐ์ฒด๋ ์ด ์๋ณ์ ๊ฐ์ ๋ณด๊ดํ๊ณ ์์ผ๋ฏ๋ก, ์๋ณ์ ๊ฐ์ ์กฐํํ๋ team.getId()๋ฅผ ํธ์ถํด๋ ํ๋ก์๋ฅผ ์ด๊ธฐํ ํ์ง ์์ต๋๋ค.
Team team = em.getReference(Team.class, 1L);
team.getId(); // ์ด๊ธฐํ ์์ฒญ X
์ํฐํฐ ์ ๊ทผ ๋ฐฉ์์ @Access(AccessType.PROPERTY) ๋ก ์ค์ ํ ๊ฒฝ์ฐ์๋ง ์ด๊ธฐํ ์์ฒญ X
์ํฐํฐ ์ ๊ทผ ๋ฐฉ์์ @Access(AccessType.FIELD) ๋ก ์ค์ ํ ๊ฒฝ์ฐ์๋ ์ด๊ธฐํ ์์ฒญ O
Member member = em.find(Member.class, 1L);
Team team = em.getReference(Team.class, 1L); // SQL ์คํ X
member.setTeam(team);
ํ๋ก์ ๊ฐ์ฒด๋ ์๋ณ์ ๊ฐ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋ณ์ ๊ฐ์ ์ฌ์ฉํ์ฌ ์ฐ๊ด๊ด๊ณ๋ฅผ ์ค์ ํ ๋๋ ํ๋ก์๋ฅผ ์ด๊ธฐํํ์ง ์์ต๋๋ค.
ํ๋ก์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผํ์๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
์ฐ๊ด๊ด๊ณ๋ฅผ ์ค์ ํ ๋๋ ์ํฐํฐ ์ ๊ทผ ๋ฐฉ์์ ํ๋๋ก ์ค์ ํด๋ ํ๋ก์๋ฅผ ์ด๊ธฐํํ์ง ์์ต๋๋ค.
ํ๋ก์ ์ด๊ธฐํ ํ์ธ
- JPA๊ฐ ์ ๊ณตํ๋ PersistenceUnitUtil.isLoaded(Object entity) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ก์ ์ธ์คํด์ค์ ์ด๊ธฐํ ์ฌ๋ถ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
boolean isLoad = em.getPersistenceUnitUtil().isLoaded(entity);
ํ๋ก์/์ค์ ๊ฐ์ฒด ํ์ธ
System.out.println("memberProxy = " + member.getClass().getName());
-> ํ๋ก์ ๊ฐ์ฒด์ ๊ฒฝ์ฐ ...javassist..
์ง์ฐ๋ก๋ฉ, ์ฆ์๋ก๋ฉ
ํ๋ก์ ๊ฐ์ฒด๋ ์ฃผ๋ก ์ฐ๊ด๋ ์ํฐํฐ๋ฅผ ์ง์ฐ๋ก๋ฉ(์ค์ ์ํฐํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ง ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์กฐํ)ํ ๋ ์ฌ์ฉํฉ๋๋ค.
์ฆ์๋ก๋ฉ์ ์ง์ฐ๋ก๋ฉ์ ๋ฐ๋๊ฐ๋ ์ผ๋ก ์ค์ ์ํฐํฐ๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ์๋ ์ํฐํฐ๋ฅผ ์กฐํํ ๋ ์ฐ๊ด๋ ์ํฐํฐ๋ฅผ ํจ๊ป ์กฐํํ๋ ๋ฐฉ์์ ๋๋ค.
์ฆ์๋ก๋ฉ ์ฌ์ฉ : ๋ค์ค์ฑ ์ด๋ ธํ ์ด์ ์ fetch ์์ฑ์ FetchType.EAGER๋ก ์ค์
@Entity
public class Member {
...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
์ค์ ์คํ๋๋ SQL
select
M.*,
T.*
from Member M
left outer join
Team T on
M.TEAM_ID = T.TEAM_ID
where M.MEMBER_ID = 1L
- ์ฆ์ ๋ก๋ฉ์ ๊ฒฝ์ฐ ์ฆ์ ๋ก๋ฉ๋๋ ์ํฐํฐ๋ค์ Joinํ๋ฉฐ ํ๋ฒ์ ์ฟผ๋ฆฌ๋ฅผ ์คํํฉ๋๋ค.
- ์ฆ์ ๋ก๋ฉ์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ด๋ถ ์กฐ์ธ(์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ๋ง ์ถ์ถ ๊ต์งํฉ)์ด ์๋ ์ธ๋ถ ์กฐ์ธ(์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ๋ , ์กฐ๊ฑด์ ๋ง์ง ์๋๋ฐ์ดํฐ๋ ํฉ์งํฉ์ผ๋ก ์ถ์ถ)ํฉ๋๋ค.
- ์กฐ๊ฑด์ ๋ง์ง ์๋ ๊ฒฝ์ฐ null ๊ฐ์ผ๋ก ์ฒ๋ฆฌ.
- ๋ด๋ถ ์กฐ์ธ์ด ์ธ๋ถ ์กฐ์ธ๋ณด๋ค ์ฑ๋ฅ์ด๋ ์ต์ ํ๋ฉด์์ ์ ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ด๋ถ ์กฐ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ป๊ฒ?
- @JoinColumn์ nullable ์์ฑ์ false๋ก ์ค์ ํ๋ฉด ๋ด๋ถ์กฐ์ธ์ ์ฌ์ฉํฉ๋๋ค.
์ง์ฐ๋ก๋ฉ ์ฌ์ฉ : ๋ค์ค์ฑ ์ด๋ ธํ ์ด์ ์ fetch ์์ฑ์ FetcchType.LAZY๋ก ์ค์
@Entity
public class Member {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
Member member = em.find(Member.class, 1L);
- Team์ ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ member๋ง ์กฐํํ๊ณ ํ์ ์กฐํํ์ง ์์ต๋๋ค.
- ๋์ team ๋ฉค๋ฒ๋ณ์์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ฃ์ด ๋ก๋๋ค!
Team team = member.getTeam(); // ํ๋ก์ ๊ฐ์ฒด!
- team์ ํ๋ก์ ๊ฐ์ฒด!
team.getName(); // ํ๋ก์ ๊ฐ์ฒด ์ด๊ธฐํ ํธ์ถํด์ ์ค์ ํ ๊ฐ์ฒด์ ๋ฉ์๋ ํธ์ถ
- ์ด๋ ๊ฒ ์ค์ ํธ์ถ์ด ์ผ์ด๋๋ ๊ฒฝ์ฐ์๋ง ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํตํด ์ค์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ๋ก๋ฉํฉ๋๋ค.
- ํ๋ก์ ๊ฐ์ฒด ์ด๊ธฐํ ๊ณผ์ ์์ select * from team where team_id = ? SQL์ด ์คํ๋ฉ๋๋ค.
+์ง์ฐ๋ก๋ฉ, ์ฆ์๋ก๋ฉ ๊ธฐ๋ณธ ์ ๋ต
์ฐ๊ด๋ ์ํฐํฐ๊ฐ ํ๋์ธ ๊ฒฝ์ฐ ( @ManyToOne, @OneToOne ) : ์ฆ์๋ก๋ฉ ์ฌ์ฉ
์ฐ๊ด๋ ์ํฐํฐ๊ฐ ์ฌ๋ฌ๊ฐ์ธ ๊ฒฝ์ฐ ( @ManyToMany, @OneToMany ) : ์ง์ฐ๋ก๋ฉ ์ฌ์ฉ
์ฐ๊ด๋์ด ์๋ ์ํฐํฐ๊ฐ ์ปฌ๋ ์ ์ธ ๊ฒฝ์ฐ ์ฑ๋ฅ์ ํ ์ด์๋ก ์ฆ์ ๋ก๋ฉ์ ๊ถ์ฅ๋์ง ์์ต๋๋ค.
+ ์ปฌ๋ ์ ์ ํ๋ก์ ๊ฐ์ฒด๊ฐ ์๋ '์ปฌ๋ ์ ๋ํผ'๋ผ๋ ํ๋ก์๊ฐ ์ง์ฐ๋ก๋ฉ์ ์ฒ๋ฆฌํด์ค๋๋ค.
<์ ๋ฆฌ>
- ์ง์ฐ๋ก๋ฉ : ์ฐ๊ด๋ ์ํฐํฐ๋ฅผ ํ๋ก์๋ก ์กฐํ. ํ๋ก์๋ฅผ ์ค์ ์ฌ์ฉํ ๋ ์ด๊ธฐํํ๋ฉด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์กฐํ
- ์ฆ์๋ก๋ฉ : ์ฐ๊ด๋ ์ํฐํฐ๋ฅผ ์ฆ์ ์กฐํ. (SQL JOIN ์ฌ์ฉ)
- ์ฆ์๋ก๋ฉ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํญ์ ์ธ๋ถ ์กฐ์ธ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ๋ด๋ถ ์กฐ์ธ์ ์ฌ์ฉํ๊ณ ์ถ์ผ๋ฉด ๋ค์ค์ฑ ์ด๋ ธํ ์ด์ ์ nullable ์์ฑ์ false๋ก ์ง์ ํ๋ฉด ๋ฉ๋๋ค.
<์ฐธ๊ณ ์๋ฃ>
'๐ Backend > Spring Data JPA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JPA] ๊ฐ ํ์ - ์๋ฒ ๋๋ ๊ฐ ํ์ , ์ปฌ๋ ์ ๊ฐ ํ์ (0) | 2023.05.08 |
---|---|
[JPA] ์์์ฑ ์ ์ด by Cascade ์ต์ (0) | 2023.05.05 |
[JPA] ๊ณ ๊ธ ๋งคํ : ๋งคํ ์ ๋ณด๋ง ์ ๊ณตํ๊ธฐ using @MappedSuperClass (0) | 2023.05.03 |
[JPA] ๊ณ ๊ธ ๋งคํ : ์์ ๊ด๊ณ ๋งคํ (0) | 2023.05.03 |
[JPA] ๋ค๋๋ค ๋จ๋ฐฉํฅ, ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ ๋งคํ (0) | 2023.05.02 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
Study Repository
rlaehddnd0422