"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."
www.inflearn.com/course/ORM-JPA-Basic#
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그
www.inflearn.com
또 하나의 역방향 삽입이 필요한 경우
테스트 케이스를 작성하는 경우에도 양방향 매핑시에 역방향 삽입을 통해 양쪽 모두에 값을 삽입해주는 과정이 필요하다.
- 테스트 케이스는 JPA 없이 순수하게 자바 코드 상태로 작성한다.
- 이 경우에도 마찬가지로 flush 나 역방향 삽입 없이 메모리에서 바로 찾아오려고 하면 아무 값도 들어있지 않은 순수한 자바 컬렉션을 가져오게 된다.
* 강사님 팁
- 역방항 삽입을 할 시 연관관계 편의 메소드를 작성하여 코딩 과정을 어느정도 간소화 시켜줄 수 있다.
- Member.java
public void setTeam(Team team) {
this.team = team;
team.getMembers().add(this);
// 연관관계 관련 메소드에 이와 같이 역방향 삽입 코드를 작성해 줄 수 있다.
}
위와 같이 코드를 작성해주면 setTeam() 메소드를 호출하여 해당 멤버 객체의 팀 데이터를 설정해주면, 자동으로 역방향 삽입 코드가 같이 수행되어 양쪽 모두에 값이 삽입되게 만들 수 있다.
양방향 매핑 시에 주의해야 할점은 또 어떤게 있을까?
양방향 매핑 시에 무한 루프를 조심해야 한다.(toString, lombok, JSON 라이브러의 경우)
- toString() 의 경우
연관관계를 가지고 있는 양쪽 모두에 toString() 을 사용해주게 되면, 한쪽에서 toString 을 사용했을 때 각자 toString 을 통해 반대편 도메인 클래스의 데이터에 대한 toString 호출을 지속적으로 반복하게 되면서 무한 루프에 걸리게 된다.
여기서 toString 뿐만 아니라 JSON 생성 라이브러리 에서도 toString() 메소드를 쭉 뽑아낸다.
그런데 양방향 연관관계가 걸려있으면 entity 를 JSON 으로 바꾸는 순간 무한 루프에 빠지게 된다.
- JSON 생성 라이브러리의 경우는 실제 운영에서 어떤 문제가 생길까?
: entity 를 controller 에서 response 로 직접 보내버리면 entity 가 양방향 연관관계가 걸려있을 경우 entity 를 JSON 으로 바꿀때 무한 루프에 빠지면서 문제가 발생하게 된다.
아래의 코드들을 보면 각자 서로 team, members 데이터를 호출해오면서 무한 루프에 빠지게 될 수 있음을 보여준다.
- Member.java
@Override
public String toString() {
return "Member{" +
"id=" + id +
", username='" + username + '\'' +
", team=" + team +
'}';
}
- Team.java
@Override
public String toString() {
return "Team{" +
"id=" + id +
", name='" + name + '\'' +
", members=" + members +
'}';
}
사실 이 경우에도 답이 정해져 있다고 한다.
- lombok 에서 toString() 만드는건 웬만하면 쓰지 않는 것이 좋다.(혹시 쓰더라도 되도록이면 빼고 쓰도록 하자)
- JSON 라이브러리의 경우 controller 에서는 entity 를 절대로 반환해서는 안된다고 한다.
-> 왜냐하면 controller 에서 entity 를 JSON 으로 api 스펙에 반환해버리면 2가지 문제가 발생하게 된다.
1. 무한 루프
2. entity 변경이 일어나는 경우 api 스펙 자체가 바뀌게 된다.
-> entity 는 웬만하면 controller 에서 DTO 로 변환해서 반환하는 것을 추천한다.
- 정리
가장 중요한 사실 : 단방향 매핑만으로도 이미 연관관계 매핑은 완료된다.
- JPA 모델링을 할 때 단방향 매핑으로 처음에 설계를 끝내야 한다(양방향 연관관계 같은거 사용하면 안됨)
- 테이블 설계를 하면서 객체 설계를 같이 들어가는데, 그 시점에 테이블 관계에서 어느정도 대략적인 외래 키가 나온다.
- 결국 N 쪽에서 단방향 매핑을 걸어서 들어가야 하는데(ManyToOne 또는 OneToOne 으로), 이때 양방향 매핑을 해선 안된다. (처음엔 일단 무조건 단방향 매핑으로 설계를 끝내라)
- 그럼 양방향 매핑은 언제 들어갈까?
-> 막상 실무에 들어가면 JPQL 에서 역방향으로 탐색할 일이 많다고 한다.(실무에서는 양방향으로 탐색해야 할 일이 많다는 뜻)
그런데 여기서 중요한 점은, 단방향 매핑을 잘 해두면 양방향 매핑은 나중에 필요할 때 추가해도 된다는 것이다.
(나중에 추가를 한다고 해도 테이블에 영향을 미치지 않는다.)
즉, 기본적으로 단방향 매핑으로 다 끝낸 다음(일 대 다 일때 그냥 N 인 곳에 연관관계 매핑을 쫙 해준다.)
실제 애플리케이션 개발하는 단계에 들어가서 양방향 매핑을 고민해도 늦지 않다.
(단, 여기서 비즈니스 로직을 기준으로 연관관계의 주인을 선택하면 안돤다, 연관관계의 주인은 외래 키의 위치를 기준으로 정해야 한다.)
'JPA' 카테고리의 다른 글
다양한 연관관계 매핑 - 2 (0) | 2020.10.04 |
---|---|
다양한 연관관계 매핑 - 1 (0) | 2020.10.03 |
연관관계 매핑 기초 - 3 (0) | 2020.09.28 |
연관관계 매핑 기초 - 2 (0) | 2020.09.28 |
연관관계 매핑 기초 - 1 (0) | 2020.09.27 |