연관관계 편의메서드 .
488
작성한 질문수 8
안녕하세요 JPA 활용 1편을보고 넘어왔습니다..
1)질문
그렇나 현재 아직 이해못한점이
연관관계 편의메서드를 사용하면 어느면서에서
이점이 발생하는지 잘모르겠습니다..
양방향관계시 연관관계메서드 에서
public void setTeam(Team team){
this.team = team;
team.getMembers().add(this);
}
team.getMembers().add(this);
이부분이 team 엔티티에서도 Member의 값을 가질수있도록 하는것으로 보여집니다만
team.getMembers().add(this); 이부분이없어도
Team team = em.find(Team.class, teamA.getId());
System.out.println("연관관계"+team.getMembers());
team.getMembers() 를해도 값이 잘 보여집니다..
어느면에서 편의가 발생하는지 감이잘 안잡힙니다 ㅠ..
2)질문
일대 다 관계에서 페치조인 쿼리로 페이징을하면 데이터 뻥튀기 때문에 위험하다고 하셨습니다.
그래서 직접 확인을해보고있는데욥
Team teamA = new Team();
teamA.setName("팀A");
em.persist(teamA);
Member member1 = new Member();
member1.setUsername("회원1");
member1.setAge(10);
member1.setTeam(teamA);
em.persist(member1);
Member member7 = new Member();
member7.setUsername("회원7");
member7.setAge(10);
member7.setTeam(teamA);
em.persist(member7);
String query = "select t from Team t join fetch t.members";
List<Team> result = em.createQuery(query,Team.class)
.setFirstResult(0)
.setMaxResults(1)
.getResultList();
for (Team team : result) {
System.out.println("팀이름 = " + team.getName());
for (Member member : team.getMembers()){
System.out.println("------------> member = " + member);
}
}
결과
딱이렇게 나왔는데 이것이 뻥튀기가 된결과인가요?
어느부분에서 위험한것인지 잘 모르겠습니다 ..
(제생각으로는 0번인덱스 페이지에 팀의값 1개가 잘 출력됫다고 생각되거든요 아니라면 팀에 맴버의 값을 1개만 출력해야하는데 두개가 출력이되어서 문제인건가요?)
답변 2
3
2. 일대다에서 fetch join 을 하면 데이터가 뻥튀기되는 이유는 fetch join 때문이 아니고 SQL 문 실행 자체가 그렇게 되기 때문입니다.
위의 fetch join 는 결국 inner join SQL문을 실행시키고 다음과 같은 결과물을 뽑습니다.
(TeamA의 ID는 1, member의 id는 각각 1, 2라 가정)
TEAM_ID, MEMBER_ID
1, 1
1, 2
즉 team은 하나밖에 없는데 멤버수만큼 row수가 뻥튀기되서 결과물이 나오게 됩니다.
일반적인 페이징 방식으로 첫 번째 레코드만 뽑는다고 하면, 위의 결과물에 첫번째 레코드만 반환을 하게 되는데 그렇게 되면 teamA에 멤버1밖에 딸려나오지 않습니다. 사용자의 의도와는 다른 결과물이 나오게 되지요. 따라서 DB단계에서의 최적화를 기대할 수 없기 때문에 DB에서 모든 데이터를 다 조회하고 메모리에서 추려내는 수밖에 없게 됩니다.
위에서는 멤버가 둘 밖에 없어서 괜찮았지만 멤버가 1000만명이었다면, 첫 1개만 뽑고싶어도 DB에서는 1000만개의 레코드를 전부 조회해서 가져온다음에 메모리 상에서 첫 1개만 추려내게 되기 때문에 의도와는 다르게 굉장히 무거운 작업이 되어버립니다.
결과적으로 말하자면, 위험하다는 기준이 의도와는 다른 잘못된 데이터를 가져올까봐 위험하다는것이 아닌 내 의도와는 다른 매우 무거운 작업이 될 확률이 매우 농후하다는 점에서 위험한 코드가 되겠습니다
2
1. 당연히 member에 team을 연결하고 나면, 추후 em.find()로 team을 가져왔을 시 team.getMembers()에 잘 반영이 되게 됩니다.
강의에서 설명하고자 했던 부분은 한 트랜잭션이 끝나기 전에는, 논리적으로는 member에 team이 들어가면 자동적으로 team에 member도 추가되어야 정상이지만 그런 효과를 단순 setter로만 누릴수는 없기 때문에 매번 member.setTeam(team), team.addMember(member) 하는게 귀찮다면 두 개 기능을 합친 메서드를 만들면 편하다는 얘기를 하신 것 같습니다
벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?
0
28
2
inheritance startegy 선택시 고려사항
0
22
1
Entity 동등성 비교
0
21
1
실무 조언 관련 질문입니다.
0
47
1
H2데이터베이스 파일 생성
0
56
2
서브쿼리 강의에서 ALL 예시 관련 질문드립니다.
0
53
2
수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?
0
52
1
JPQL 메소드와 락
0
55
1
Delivery @OneToOne
0
60
1
17강 4~5분대 테이블 값 조회가 안됩니다.
0
94
2
UnsupportedOperationException 발생
0
86
3
H2 Database 연결이 안됩니다.
0
95
2
연관관계 매핑 질문드립니다.
0
85
2
h2데이터베이스 실행오류
0
108
2
persistence.xml
0
108
2
양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?
0
80
1
영속성 컨텍스트
0
66
1
JPA 프록시
0
96
1
Native Query와 MyBatis
0
70
1
영속성 컨텍스트는 어떤 메모리에 저장되는건가요?
0
87
1
임베디드 타입 예시 코드 관련 질문
0
115
3
명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요
0
95
3
인텔리제이 패키지 커서 단축키 질문
0
108
2
혹시 현재는 ID 데이터 타입이 String이면 안되나요?
0
145
1





