์๋ฐ ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ - ๊ธฐ๋ณธํธ์ ๊ณต๋ถํ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
๐ ์๋ฐฉํฅ ๋งคํ
์ ์ ํ๋ ๋จ๋ฐฉํฅ ๋งคํ์์ Team ํ ์ด๋ธ์ Member๋ฅผ List๋ก ์ถ๊ฐํด์ค์ ์๋ฐฉํฅ์ผ๋ก ๋งคํ ์ํค๋ ๊ฒ์ด๋ค.
@Entity
public class Team {
@Id @GenerateValue
private Long id;
private String name;
@OneToMany(mappedBy = "team") // Memberํด๋์ค์ ์๋ team ๊ฐ์ฒด์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
private List<Member> members = new ArrayList<Member>();
}
@Entity
public class Member {
...
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team; // <--------- team์ mappedBy๋ก ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
}
์ธ๋ํค ํ๋๋ก ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง๊ฒ ๋์ด์ -> ์์ชฝ์ผ๋ก ์กฐ์ธํ ์ ์๋ค.
SELECT *
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
SELECT *
FROM TEAM T
JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID
โ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ(Owner)
์๋ฐฉํฅ ๋งคํ ๊ท์น
์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ (Member) | ์ฃผ์ธ์ด ์๋ ์ชฝ (Team) |
@ManyToOne @JoinColumn(name = "TEAM_ID") private Team team; |
@OneToMany(mappedBy = "team") |
์ธ๋ํค๋ฅผ ๊ด๋ฆฌ(๋ฑ๋ก, ์์ ๊ฐ๋ฅ) | ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ |
Member์ Team์ ์ฃผ์ธ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ด ์ข๋ค. ์ผ๋ ๋ค ์ผ๋, ๋ค ์ชฝ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ๋๋๊ฒ ๊ฐ์ฅ ์ข๋ค.
!! ์๋ฐฉํฅ ๋งคํ์ ๊ฐ์ฅ ๋ง์ด ํ๋ ์ค์
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
// ์ญ๋ฐฉํฅ ๋ง ์ฐ๊ด๊ด๊ณ ์ค์ ?
team.getMembers().add(member);
em.persist(member);
์์ชฝ ๋ค ๊ฐ์ ์ ๋ ฅํด์ฃผ๋ ๊ฒ์ด ์ข๋ค!
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
team.getMembers().add(member);
member.setTeam(team); // ** ์์ชฝ๋ค ๊ฐ์ ๋ฃ์ด์ค๋ค!
em.persist(member);
์์ ๊ฐ์ฒด ์ํ๋ฅผ ๊ณ ๋ คํด์ ํญ์ ์์ชฝ์ ๊ฐ์ ์ค์ ํด์ผํ๋ค.
โ ์ฐ๊ด๊ด๊ณ ํธ์ ๋ฉ์๋ ์์ฑ
์์ชฝ์ ์ฐ๊ด๊ด๊ณ๋ฅผ ์ค์ ํ๋๊ฑธ ๊น๋จน์์ ์์ผ๋๊น ํธ์์ ์๋์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋๊ฒ์ด ์ข๋ค.
Team team = new Team();
...
Member member = new Member();
member.setUserName("memberA");
member.setTeam(team); // member.team ์ฐ๊ด๊ด๊ณ ์ค์
em.persist(member);
team.getMembers().add(member); // ์ด ์ฝ๋๋ฅผ ๊น๋จน์ ์ ์์ผ๋๊น setTeam ๋ฉ์๋์ ์ถ๊ฐ ์์ผ์ค๋ค.
------------------------------------
// (Member) ์ setTeam์ ์ค์ ํ ๋, team์ list์ ํจ๊ป ์ ์ฅํ๊ฒ๋ ์ค์ ํด์ค๋ค.
public void setTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
์ฌ์ค์ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ชฝ์๋ง ๊ฐ ์ธํ ํด์ค๋ ๊ฐ์ ์ ๋ค์ด๊ฐ๋ค.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
em.persist(member);
em.flush();
em.clear();
// team.getMembers().add(member); <- team์ ์ด์ฐจํผ ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ฟผ๋ฆฌ ๋ ๋ฆด ๋, jpa๊ฐ ์ณ๋ค๋ ์๋ณธ๋ค.
member.setTeam(team);
Team team = em.find(Team.class, team.getId());
System.out.println(team.getMembers().get(0).getName()); // member1
team.getMembers().add(member)๋ฅผ ์ํด์ค๋, ๊ฐ์ ์ฐ์ด๋ณด๋ฉด ์ปฌ๋ ์ ์ ๊ฐ์ด ๋ค์ด์๋ค.
๊ทผ๋ฐ ํด์ฃผ๋ ์ด์ ๋ ๋ญ๊น?
๋์ค์ ์์ํ๊ฒ ์๋ฐ ์ฝ๋๋ก ํ ์คํธ ์ผ์ด์ค๋ฅผ ์์ฑํ ๋, ๊ทธ๋ ํผ๋์ ์ค ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์์ํ ์๋ฐ ๊ฐ์ฒด ์ํ๋ฅผ ๊ณ ๋ ค ํ์ฌ ์์ชฝ์๋ค๊ฐ ๊ฐ์ ๋ฃ์ด์ฃผ๋๊ฒ ์ข๋ค!
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
em.persist(member);
// em.flush(); ์ด ์ฝ๋๊ฐ ์คํ์ด ์๋๊ธฐ ๋๋ฌธ์, ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ์ง ์๋๋ค.
// em.clear();
member.setTeam(team);
Team team = em.find(Team.class, team.getId()); // 1์ฐจ ์บ์์์ ๊บผ๋ด์ด
System.out.println(team.getMembers().get(0).getName()); // error!
์ด๋ฌํ ์ด์ ๋๋ฌธ์, ์์ชฝ์๋ค๊ฐ ๊ฐ์ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค!!
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeam(team); // team ์ค์
em.persist(member);
em.flush();
em.clear();
Team team = em.find(Team.class, team.getId());
System.out.println(team.getMembers().get(0).getName()); // member1
team์ ๋ํด์๋ persist๋ฅผ ํ์ง ์์๋ ๋๋ค. ์ฐ๊ด๊ด๊ณ ์ฃผ์ธ์ธ member ์ชฝ์์ persist๋ฅผ ํ๋ฉด ์๋์ผ๋ก ์ ์ฅ์ด ๋๋ค!