양방향 연관관계도 테이블 구조는 똑같다.(조인을 하면 되기 때문)
하지만 객체 입장에서 보면?
Team에도 List를 넣어줘야 한다.
결과를 먼저 봐보면 Member는 그대로이고,
import javax.persistence.*;
@Entity // Entity는 JPA에서 관리하는 것임을 나타냄
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
}
Team에는 List가 추가되어 있는 것을 확인할 수 있다.
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
public List<Member> getMembers() {
return members;
}
public void setMembers(List<Member> members) {
this.members = members;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
그런데
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
여기서 mappedBy는 어떤 것이랑 연결되어 있는가를 나타내는 것인데 이것은 Member 엔티티에서의 변수 이름 즉,
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
의 변수이름 team을 나타낸다.
그리고 나서 결과를 확인해보면,
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
em.persist(member);
em.flush();
em.clear();
Team findTeam = em.find(Team.class, team.getId());
List<Member> members = findTeam.getMembers();
System.out.println("===================");
for (Member m : members) {
System.out.println("m.getUsername() = " + m.getUsername());
}
System.out.println("===================");
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
제대로 나오는 것을 확인할 수 있다.
사실 단방향 관계로 하는 것이 최대한 좋다 양방향은 신경쓸게 많기 때문
일단 제대로 이해를 하려면
객체와 테이블 간에 연관관계를 맺는 차이를 이해해야 한다.
그림을 다시보면
테이블 같은 경우에는 TEAM_ID 값 하나로 조인을 이용해서 양쪽다 필요한 정보를 얻을 수 있다.
하지막 객체 입장에서는
Member는 team을 통해서 Team은 members를 통해서 서로를 접근한다.
즉, 단방향 연관관계가 2개 있는 것이다.
여기서 문제가 하나가 발생하는데,
멤버 입장에서 팀을 바꾸고 싶을 때, Member 엔티티에서 팀을 바꿔야할지 팀 엔티티에서 팀을 바꿔야할지 의문을 가지게 된다.
결론을 말하면 룰이 생기는데, 둘 중 하나로 외래키를 관리해야 한다. 즉, 주인을 정해야 한다.
그리고 외래 키가 있는 곳을 주인으로 설정하는 것이 좋다고 한다. 즉 위의 테이블에서 Member.team을 주인으로 한다.
일단 간단한 이유는 TEAM의 members를 바꿨을 때 Member 라는 다른 테이블에 업데이트 쿼리를 날리게 된다. 즉 관리가 힘들어 진다.
[ JPA ] persist 와 id값 (0) | 2022.01.09 |
---|---|
[ JPA ] 양방향 연관관계(2) - 주의할 점 (0) | 2022.01.08 |
[ JPA ] 단방향 연관관계 (0) | 2021.12.30 |
[ JPA ] @Entity (0) | 2021.12.19 |
[ JPA ] JPA로 DB 데이터 삽입 (0) | 2021.12.16 |