ํ๋ก์?
Member ์ํฐํฐ์ Team ์ํฐํฐ๋ @Many(Member)ToOne(Team) ๊ด๊ณ์ ์๋ค.
Member๋ฅผ ์กฐํํ ๋, Team์ ํญ์ ์กฐํํ๊ฒ ๋๋ค๋ฉด? - ๋ญ๋น๊ฐ ์์ฒญ๋๊ฒ ๋ฐ์ํ๋ค.
๋น์ฆ๋์ค ๋ก์ง์์ ํ์ํ์ง ์์ ๊ฒฝ์ฐ, ํญ์ Team์ ์กฐํํด์ ๊ฐ์ ธ์ฌ ์ด์ ๋ ์๋ค!
JPA๋ ์ด ๋ญ๋น๋ฅผ ํ์ง ์๊ธฐ ์ํด, ์ง์ฐ๋ก๋ฉ๊ณผ ํ๋ก์๋ผ๋ ๊ฐ๋ ์ผ๋ก ํด๊ฒฐํ๋ค.
์ง์ฐ๋ก๋ฉ
JPA์๋ em.find()์ em.getReference()๋ผ๋ ๋ฉ์๋๊ฐ ์กด์ฌํ๋ค.
em.find() : DB๋ฅผ ํตํด์ ์ค์ ์ํฐํฐ ๊ฐ์ฒด ์กฐํ
em.getReference() : DB์ ์กฐํ๋ฅผ ๋ฏธ๋ฃจ๋ ๊ฐ์ง(ํ๋ก์) ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ์กฐํ
Member ์ํฐํฐ
@Entity
@Getter
@Setter
public class Member extends BaseEntity {
โ
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
โ
@Column(name = "name")
private String username;
โ
private Integer age;
โ
@Enumerated(EnumType.STRING)
private RoleType roleType;
โ
@Lob
private String description;
โ
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
โ
@OneToOne
@JoinColumn(name = "locker_id")
private Locker locker;
โ
@OneToMany(mappedBy = "member")
private List<MemberProduct> memberProducts = new ArrayList<>();
}
em.find()๋ก ๋ฉค๋ฒ๋ฅผ ์กฐํํ๋ฉด, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฟผ๋ฆฌ๊ฐ ๋ฐ๋ก ๋๊ฐ๋ค.
Member member = new Member();
member.setCreatedBy("creator");
โ
em.persist(member);
โ
em.flush();
em.clear();
โ
Member findMember = em.find(Member.class, member.getId());
System.out.println("findMember.id = " + findMember.getId());
System.out.println("findMember.username = " + findMember.getUsername());
โ
tx.commit();
๊ฒฐ๊ณผ
Hibernate:
/* insert hello.jpa.Member
*/ insert
into
Member
(id, createdBy, createdDate, lastModifiedBy, lastModifiedDate, age, description, locker_id, roleType, name)
values
(null, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate:
select
member0_.id as id1_4_0_,
member0_.createdBy as createdB2_4_0_,
member0_.createdDate as createdD3_4_0_,
member0_.lastModifiedBy as lastModi4_4_0_,
member0_.lastModifiedDate as lastModi5_4_0_,
member0_.age as age6_4_0_,
member0_.description as descript7_4_0_,
member0_.locker_id as locker_10_4_0_,
member0_.roleType as roleType8_4_0_,
member0_.team_id as team_id11_4_0_,
member0_.name as name9_4_0_,
locker1_.id as id1_3_1_,
locker1_.name as name2_3_1_,
team2_.id as id1_8_2_,
team2_.createdBy as createdB2_8_2_,
team2_.createdDate as createdD3_8_2_,
team2_.lastModifiedBy as lastModi4_8_2_,
team2_.lastModifiedDate as lastModi5_8_2_,
team2_.name as name6_8_2_
from
Member member0_
left outer join
Locker locker1_
on member0_.locker_id=locker1_.id
left outer join
Team team2_
on member0_.team_id=team2_.id
where
member0_.id=?
findMember.id = 1
findMember.username = creator
๋ฐ๋๋ก, em.getReference()๋ก ๋ฉค๋ฒ๋ฅผ ์กฐํํ๋ฉด, ํ์ํ ์์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๋ค.
findMember.usernameํ๋๋ฅผ ์ถ๋ ฅํ ์์ ์ DB๋ฅผ ์กฐํํ๋ ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๊ฒ ๋๋ค.
findMember.getClass()๋ก ๊ฐ์ฒด๋ฅผ ํ์ธํ๋ฉด, Member๊ฐ์ฒด๊ฐ ์๋, ํ์ด๋ฒ๋ค์ดํธ๊ฐ ๊ฐ์ ๋ก ๋ง๋ ๊ฐ์ง ํด๋์ค(HibernateProxy) ๊ฐ์ฒด์ด๋ค.
Member member = new Member();
member.setUsername("creator");
โ
em.persist(member);
โ
em.flush();
em.clear();
โ
Member findMember = em.getReference(Member.class, member.getId());
System.out.println("findMember = " + findMember.getClass());
System.out.println("findMember.id = " + findMember.getId());
System.out.println("findMember.username = " + findMember.getUsername());
โ
tx.commit();
Hibernate:
/* insert hello.jpa.Member
*/ insert
into
Member
(id, createdBy, createdDate, lastModifiedBy, lastModifiedDate, age, description, locker_id, roleType, name)
values
(null, ?, ?, ?, ?, ?, ?, ?, ?, ?)
findMember = class hello.jpa.Member$HibernateProxy$yJgMgbkR
findMember.id = 1
Hibernate:
select
member0_.id as id1_4_0_,
member0_.createdBy as createdB2_4_0_,
member0_.createdDate as createdD3_4_0_,
member0_.lastModifiedBy as lastModi4_4_0_,
member0_.lastModifiedDate as lastModi5_4_0_,
member0_.age as age6_4_0_,
member0_.description as descript7_4_0_,
member0_.locker_id as locker_10_4_0_,
member0_.roleType as roleType8_4_0_,
member0_.team_id as team_id11_4_0_,
member0_.name as name9_4_0_,
locker1_.id as id1_3_1_,
locker1_.name as name2_3_1_,
team2_.id as id1_8_2_,
team2_.createdBy as createdB2_8_2_,
team2_.createdDate as createdD3_8_2_,
team2_.lastModifiedBy as lastModi4_8_2_,
team2_.lastModifiedDate as lastModi5_8_2_,
team2_.name as name6_8_2_
from
Member member0_
left outer join
Locker locker1_
on member0_.locker_id=locker1_.id
left outer join
Team team2_
on member0_.team_id=team2_.id
where
member0_.id=?
findMember.username = creator
ํ๋ก์ ํน์ง
์ค์ ํด๋์ฌ๋ฅผ ์์ ๋ฐ์์ ๋ง๋ค์ด์ง๋ค. (๊ฒ๋ชจ์์ด ๊ฐ๋ค)
์ฌ์ฉํ๋ ์ ์ฅ์์, ์ง์ง ๊ฐ์ฒด์ธ์ง ํ๋ก์ ๊ฐ์ฒด์ธ์ง ๊ตฌ๋ถํ์ง ์๊ณ ์ฌ์ฉํ๋ฉด ๋๋ค.
ํ๋ก์ ๊ฐ์ฒด๋ ์ค์ ๊ฐ์ฒด์ ์ฐธ์กฐ(target)์ ๋ณด๊ดํ๋ค.
ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ ์ค์ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
ํ๋ก์ ๊ฐ์ฒด์ ์ด๊ธฐํ
Member member = em.getReference(Member.class, “id1”);
member.getName();
1. em.getReference()๋ก ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์จ ๋ค์, getName() ๋ฉ์๋๋ฅผ ํธ์ถ
2. MemberProxy๊ฐ์ฒด์ target๊ฐ์ด ์ฒ์์๋ ์กด์ฌํ์ง ์๋๋ค. JPA๊ฐ ์์์ฑ ์ปจํ ์คํธ์ ์ด๊ธฐํ ์์ฒญ์ ํ๋ค.
3. ์์์ฑ ์ปจํ ์คํธ๊ฐ DB์ ์กฐํํด์ ์ค์ Entity๋ฅผ ์์ฑํด์ค๋ค.
4. ํ๋ก์ ๊ฐ์ฒด๊ฐ ๊ฐ์ง๊ณ ์๋ target(์ค์ Member Entity)์ getName()์ ํธ์ถํด์ member.getName()์ ํธ์ถํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ ์ ์๋ค.
5. ํ๋ก์ ๊ฐ์ฒด์ target์ด ํ ๋น๋๊ณ ๋๋ฉด, ๋์ด์ ํ๋ก์ ๊ฐ์ฒด์ ์ด๊ธฐํ ๋์์ ์์ด๋ ๋จ.
ํ๋ก์ ํน์ง ์ ๋ฆฌ
- ํ๋ก์ ๊ฐ์ฒด๋ ์ฒ์ ์ฌ์ฉํ ๋, ํ๋ฒ๋ง ์ด๊ธฐํ
- ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํ ํ ๋, ํ๋ก์ ๊ฐ์ฒด๊ฐ ์ค์ ๋ก ์ํฐํฐ๋ก ๋ฐ๋๋ ๊ฒ์ ์๋๋ค.
- ์ด๊ธฐํ ๋๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํตํด์ ์ค์ ์ํฐํฐ์ ์ ๊ทผ ๊ฐ๋ฅํ ๊ฒ
- target์ ๊ฐ์ด ์ฑ์์ง๋ ๊ฒ
- ํ๋ก์ ๊ฐ์ฒด์ ์๋ณธ ๊ฐ์ฒด๊ฐ ํ์ ์ด ๋ค๋ฅด๋ค. ํ์ ์ฒดํฌ์ ์ฃผ์ํด์ผํ๋ค. == ๋น๊ต X, instanceOf ๋ฅผ ์ฌ์ฉํด์ผํจ
Member find = em.find(Member.class, member1.getId());
Member reference = em.getReference(Member.class, member2.getId());
System.out.println("m1 == m2 : " + (m1 == m2)); // false
System.out.println("find : " + (find instanceof Member)); // true
System.out.println("reference : " + (reference instanceof Member)); // true
- ์์์ฑ ์ปจํ
์คํธ์ ์ฐพ๋ ์ํฐํฐ๊ฐ ์ด๋ฏธ ์์ผ๋ฉด, em.getReference()๋ฅผ ํธ์ถํด๋ ์ค์ ์ํฐํฐ๋ฅผ ๋ฐํํ๋ค.
- JPA๋ ํ๋์ ์์์ฑ ์ปจํ ์คํธ์์ ์กฐํํ๋ ๊ฐ์ ์ํฐํฐ์ ๋์ผ์ฑ์ ๋ณด์ฅํ๋ค.
- em.getReference()๋ก ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๊ตณ์ด ๊ฐ์ ธ์ค์ง ์๋๋ค
Member find = em.find(Member.class, member.getId());
Member reference = em.getReference(Member.class, member.getId());
โ
System.out.println("find == reference : " + (find == reference)); // true
- ๋๋ค getReference()๋ก ๊ฐ์ ธ์ค๊ฒ ๋๋ค๋ฉด
- ๋๋ค ๊ฐ์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์กฐํ.
- JPA๋ ํ ํธ๋์ญ์ ์์ ์กฐํํ๋ ๊ฐ์ ์ํฐํฐ์ ๋์ผ์ฑ์ ๋ณด์ฅํ๋ค. ํ๋ก์ ๊ฐ์ฒด์ ๋์ผ์ฑ๋ ๋ณด์ฅํจ!
Member reference1 = em.getReference(Member.class, member.getId());
Member reference2 = em.getReference(Member.class, member.getId());
โ
System.out.println("reference1 == reference2 : " + (reference1 == reference2)); // true
- getReference()๋ก ๋จผ์ ๊ฐ์ ธ์ค๊ณ , find()๋ก ์ค์ ๊ฐ์ฒด๋ฅผ ์กฐํํ๋ฉด?
- ๋๋ค ๊ฐ์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค. (ํ ํธ๋์ญ์ ์์ ์กฐํํ๋ ๊ฐ์ ์ํฐํฐ์ ๋์ผ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด์)
Member reference = em.getReference(Member.class, member.getId());
Member find = em.find(Member.class, member.getId());
โ
System.out.println("reference == find : " + (reference == find)); // true
์ค๋ฌด์์ ๋ง์ด ๋ง๋๊ฒ ๋๋ ๋ฌธ์
์์์ฑ ์ปจํ ์คํธ์ ๋์์ ๋ฐ์ ์ ์๋ ์ค์์ ์ํ์ผ๋, ์ด๊ธฐํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
ํธ๋์ญ์ ์ ๋ฒ์ ๋ฐ์์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์กฐํํ๋ ค๊ณ ํ ๋!
Member member = new Member();
member.setUsername("creator");
โ
em.persist(member);
โ
em.flush();
em.clear();
โ
Member reference = em.getReference(Member.class, member.getId());
โ
em.detach(reference);
//em.close, em.clear ๋ชจ๋
โ
System.out.println("findMember.username = " + reference.getUsername());
โ
tx.commit();
- ํ์ด๋ฒ๋ค์ดํธ๋ org.hibernate.LazyInitializationException ์์ธ๋ฅผ ํฐํธ๋ฆฐ๋ค.
org.hibernate.LazyInitializationException: could not initialize proxy [hello.jpa.Member#1] - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:169)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:309)
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45)
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
at hello.jpa.Member$HibernateProxy$bCLaGKb1.getUsername(Unknown Source)
at JpaMain.main(JpaMain.java:35)
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ Spring boot์์ open-in-view์ค์ ์ true๋ก ๊ฐ์ ธ๊ฐ.
์ฐธ์กฐ
https://kingbbode.tistory.com/27
https://www.inflearn.com/course/ORM-JPA-Basic
'Server๐งค > JPA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JPA] Java Persistence API (0) | 2023.06.12 |
---|---|
[SpringDataJPA] save(), saveAll() ์ฐจ์ด (0) | 2023.05.14 |
[JPA] ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ (0) | 2023.02.03 |
[JPA] ์ฐ๊ด๊ด๊ณ ๋งคํ (๋จ๋ฐฉํฅ ๋งคํ) (0) | 2023.02.03 |
[SpringBoot๊ณผ JPA ํ์ฉ1] H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์น์ DB์ฐ๊ฒฐ, ์ฟผ๋ฆฌํ๋ผ๋ฏธํฐ ๋ก๊ทธ ์ฐ๋ ๋ฐฉ๋ฒ (0) | 2022.08.08 |