Java/JPA

연관관계 매핑(양방향)

amungstudy 2023. 11. 15. 12:36

가급적이면 단방향으로 설계하시오!

단방향 매핑만으로도 이미 객체랑 테이블 연관관계 매핑은 완료.

단방향 매핑을 잘하고 양방향은 필요할 때 추가해라.(양방향 매핑은 반대방향으로 조회 기능(객체 그래프 탐색)이 추가된 것 뿐임)

 

실무에서는 JPQL에서 역방향으로 탐색할 일이 많음. 필요할 때 추가하면 됨. (테이블에 영향 없음)

 

@Entity @Getter @Setter
public class Team {
    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;
    @OneToMany(mappedBy = "team") // Member의 Team타입의 변수명
    private List<Member> members = new ArrayList<>(); // nullpoint방지하는 관례

 

외래 키가 있는 곳(1:N 관계에서 N인 곳)을 주인으로 정해라

1. 성능이슈

2. 설계깔끔

 

주인이 아닌 쪽은 읽기만 가능,

주인은 mappedBY 속성 사용 X

주인이 아니면 mappedBy 속성으로 주인 지정.

 

**** 양방향 매핑시 가장 많이 하는 실수 : 연관관계의 주인에 값을 입력해야한다!

주인이 아닌 곳에 넣고 처리하면 DB에 null되어버림

 

**** 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자.( 주인에만 값을 입력하면 되긴 하지만...)

 

방법1. 

연관관계 편의 메소드를 생성하자. ( 메소드 사용하면 한방에 양쪽 다 바꿈)  (setter대신 이름을 정해주었다.)

 

두 군데 중 한군데에서만 사용하기!(잘못하면 무한루프걸림)

1번째 방법 : Member에서 메소드 만들기

public void changeTeam(Team team) {
    this.team = team;
    team.getMembers().add(this);
}

2번째 방법 : Team에서 메소드 만들기

public void addMember(Member member) {
    member.setTeam(this);
    members.add(member);
}

 

**양방향 매핑시 무한루프 주의!!

1) toString하면 StackOverflowError 발생한다!!

Member.toString()하면 안에 있는 Team.toString() 하면 Members.toString() 하면 ............

 

2) lombok의 @Data 쓰면 toString써버리니까.... 안돼안돼....

 

3) JSON 생성 라이브러리로 무한루프 발생가능.

컨트롤러에서 Entity 반환하지 마라!(JSON으로 api 반환해버리면 무한루프, 객체 api 스펙이 바껴버림)

DTO로 반환해라

 


N:M 관계는 1:N, N:1로

실전에서는 @ManyToMany를 사용하지 않는다.(중간 테이블이 단순하지 않다)

따라서 연결 테이블용 엔티티를 추가한다(다대다를 1:다,다:1로 연결하는 연결 테이블을 엔티티로 승격)