ecsimsw

JPA / 객체를 고려한 양방향 연관 / 연관관계 편의 메소드 본문

JPA / 객체를 고려한 양방향 연관 / 연관관계 편의 메소드

JinHwan Kim 2020. 6. 30. 04:40

순수 객체를 고려한 양방향 연관

 

  아래 코드에서 출력되는 member는 0개이다. 

 

  매니저를 flush하기 전에는 버퍼에 sql이 저장되어만 있기 때문이다.

Member memberA = new Member();
memberA.setName("memberA");
memberA.setTeam(teamA);

for(Member m : teamA.getMembers()){
   System.out.println(m.getName());
}

  객체를 고려하여 양방향 연관을 구현하려면 teamA에도 member를 넣어줘야한다.

 

  물론 그게 멤버 엔티티의 수정을 만들지는 않지만.

Member memberA = new Member();
memberA.setName("memberA");
memberA.setTeam(teamA);
teamA.getMembers().add(memberA);

for(Member m : teamA.getMembers()){
    System.out.println(m.getName());
}

  이렇게하면 flush 이전에도 정상적으로 teamA에 memberA가 포함되도록 할 수 있다.

 

 

연관관계 편의 메소드

 

  memberA가 setTeam()을 호출할 때 teamA.getMembers().add(memberA) 가 같이 호출되면 어떨까.

 

  Member가 member의 주인라고 하더라도 결국 setTeam을 호출할 때 team의 members에 자신을 넣어야하니 말이다.

public class Member{
  private Team team;
  
  public void setTeam(Team team) {
    this.team = team;
    team.getMembers().add(this);
  }
}

  아래 코드의 결과는 teamA, teamB 모두 member를 같는 것으로 된다. 

member.setTeam(teamA);
member.setTeam(teamB);

Member findMember = teamA.getMember(); 
Member findMember = teamB.getMember(); 

 

  이를 해결하기 위해 만약 현재 member에 team이 있다면 "if(this.team != null)", 현재 속한 team의 members에서 본인을 삭제한다.

 

  따라서 최종 연관관계 편의 메소드는 다음과 같다.

public class Member{
  private Team team;
  
  public void setTeam(Team team) {
    if(this.team != null) {	
        this.team.getMembers().remove(this);	
    }
    
    this.team = team;
    team.getMembers().add(this);
  }
}
Comments