[자바 ORM 표준 JPA 프로그래밍 - 기본편] 5-3강
https://inf.run/2zDo 강의를 수강하고 작성하는 게시물입니다.
양방향 매핑시 자주하는 실수
연관관계의 주인에 값을 입력하지 않음
테이블은 FK를 이용하여 관리가 되기 때문에 연관관계 주인에 매핑되는 것이 중요하다.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em.persist(member);
이럴 경우 Member에 Team이 매핑되지 않으므로 테이블에 적용되지 않는다.
사실 JPA 입장에서는 주인에만 넣으면 되는 코드이지만 객체 관계를 고려하면 아래처럼 양쪽에 넣어주는게 완벽하다.(순수 코드로만 테스트할때도 양쪽으로 하는것이 편하다.)
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);
실수를 없애기 위해 정하기!
- 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자
- 연관관계 편의 메소드를 생성하자
- 양방향 매핑시에 무한 루프를 조심하자
- 예: toString(), lombok, JSON 생성 라이브러리
연관관계 편의 메서드
//Member.java
public void setTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
근데 로직이 들어가는 메서드 이름에서 set을 넣는건 위험부담이 좀 있다. 그래서 changeTeam같이 이름을 바꾸는 것을 추천한다.
사실 이렇게 넣으면서 null 체크도 하고 해야할 것이 많다.(이미 연결된 것을 뺀다거나 해야한다.)
근데 편의를 위해서 연관관계의 주인이 아닌곳에서도 추가할 수 있도록 메서드를 집어넣는다.
//Team.java
public void addMember(Member member) {
member.setTeam(this);
members.add(member);
}
양방향 매핑시 무한루프 주의
toString(), lombok, JSON 생성 라이브러리
위와 같은것들을 사용할때 양쪽을 서로 참조해서 무한루프 상황을 조심해야 한다.
toString을 예로들면 각자 객체로 들어가 또 toString을 하므로 참조참조가 된다.
실제로 실무에서 Controller에서 entity를 바로 반영을 할 경우 entity를 Json으로 바꿀때 타고타고 무한루프를 탈 수 있다.
추천하는 것은 Controller에서 entity를 API스펙으로 바로 바꾸지 마라. dto로 변환해서 반환하는 것을 추천한다.
양방향 매핑 정리
단방향 매핑만으로도 이미 연관관계 매핑은 완료된 것이다.
양방향 매핑은 반대방향으로 조회 기능이 추가된 것 뿐이다.
사실 설계시에는 양방향매핑은 고려할게 너무 많아진다. 그래서 대부분 단방향으로 매핑하는 것이 좋다.
단방향 매핑을 잘 한 후 나중에 양방향은 추가할 수 있다.(테이블에 영향을 주지 않는다.)
연관관계의 주인을 정하는 기준
- 비즈니스 로직을 기준으로 연관관계의 주인을 선택하면 안됨
- 연관관계의 주인은 외래 키의 위치를 기준으로 정해야함
댓글 남기기