
아래의 코드는 연관관계가 없는 객체, 참조 대신에 외래키를 그대로 쓰게 되어있다.
// 외래키를 그대로 쓰는 객체의 필드
@Column(name = "TEAM_ID")
private Long teamId;
// 외래키 식별자를 직접 다룸
member.setTeamId(team.getId());
// 조회 시에도 연관관계가 존재하지 않아 식별자로 다시 조회해야함
Team findTeam = em.find(Team.class, member.getTeamId());
결국, 데이터 중심 설계에서 객체 지향적 설계로 변경하기 위해서는 연관관계 매핑이 필수적이라는 것.
객체 지향 모델링 시에 객체 연관관계 사용을 위해 새로운 어노테이션을 사용한다.
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
예시 속 어노테이션은 다대일 (ManyToOne) 관계에서 팀 테이블 속 매핑되는 컬럼(JoinColumn)을 알려주는 것이다.
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeam(team); //단방향 연관관계 설정, 참조 저장
em.persist(member);
저장 시에는 객체를 저장하고 저장 객체의 지정된 테이블에서 PK 값을 찾아와 저장
//조회
Member findMember = em.find(Member.class, member.getId());
//참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam();
조회 시에는 참조로 연관관계를 조회 (객체 그래프 탐색)
// 새로운 팀B
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);
// 회원1에 새로운 팀B 설정
member.setTeam(teamB);
수정 시에는 연관 관계를 사용하여 새로운 객체로 쉽게 교체 (FK 값 변경)
연관관계의 주인은 단방향 매핑과 똑같이 설정함 (@ManyToOne, @JoinColumn)
연관 관계가 아닌 쪽은 @OneToMany(mappedBy = "") 설정을 해줌 (값은 연관관계 주인의 필드명을 사용)
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
양방향 매핑이란 결국 단방향 객체 연관관계 + 반대 방향으로 객체 그래프 탐색이 가능하게 만드는 것이다.
객체의 연관 관계는 단방향 2개다. 반면 테이블의 연관관계는 양방향 1개 (FK 하나로 두 테이블의 연관관계를 정리한다)
즉, 객체 둘 중 하나로 외래키를 관리해야된다는 것이다.
양방향 매핑의 규칙
양방향 매핑 시에 DB에 반영되게 하려면 주인에 값을 매핑해야함 (순수객체관계 고려 시에는 양쪽 다 입력)
주의점: 양쪽에 값을 설정해주고 (순수 객체 상태)
연관관계 편의 메소드를 생성해주어야한다. (주인 엔티티 생성 시에 양방향 매핑을 구현하는 메소드)
무한 루프를 조심해야함 (toString, lombok, JSON Library 등등)
비즈니스 로직을 기준으로 주인을 설정하지 않고 외래키 위치를 기준으로 주인을 정하자