작성
·
379
2
안녕하세요. 다대일 양방향 관계에 대해 질문 드립니다.
Member 엔티티와 Team 엔티티가 다대일 양방향 맵핑 되어있고,
package hellojpa;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Member {
@Id
@GeneratedValue
@Column(name= "MEMBER_ID")
private Long id;
private String name;
private int age;
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<Order>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
}
package hellojpa;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team",fetch = FetchType.LAZY)
private List<Member> members = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public List<Member> getMembers() {
return members;
}
public void setName(String name) {
this.name = name;
}
}
팀에서 getMembers 메소드를 통하여 해당 팀에 소속된 멤버들을 조회할 때
public class hellojpa {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
Member member =new Member();
member.setName("member1");
member.setAge(20);
Team team = new Team();
team.setName("team a");
em.persist(team);
member.setTeam(team);
em.persist(member);
Member member2 = new Member();
member2.setName("member222");
member2.setTeam(team);
em.persist(member2);
em.flush();
em.clear();
List<Member> memberList = em.find(Team.class, team.getId()).getMembers();
for (Member member1 : memberList) {
System.out.println(member1.getName());
}
} catch (Exception e) {
transaction.rollback();
} finally {
em.close();
}
emf.close();
}
}
저는
select
member0_.MEMBER_ID
members0_.TEAM_ID
members0_.age
members0_.name
from
Member members0_
where
members0_.TEAM_ID=?
이러한 쿼리가 생성될 것으로 예상했습니다.
하지만 실제 쿼리가 나간것을 확인해보니
select
members0_.TEAM_ID as team_id4_0_0_,
members0_.MEMBER_ID as member_i1_0_0_,
members0_.MEMBER_ID as member_i1_0_1_,
members0_.age as age2_0_1_,
members0_.name as name3_0_1_,
members0_.TEAM_ID as team_id4_0_1_
from
Member members0_
where
members0_.TEAM_ID=?
select문에서 특정 컬럼들이 중복되어 표시되는데(bold표시), 혹시 이렇게 표시되는게 정상적인 것인지 혹은 맵핑 과정에서 실수가 있었던지 궁금하여 질문 드립니다!
답변 2
4
안녕하세요. dlalswotl님
이것은 @OneToMany 상황에서 지연로딩인 경우에만 발생합니다.
먼저 이렇게 사용한다고 해서 어떤 문제가 발생하는 것은 아닙니다.
저도 정확한 이유는 모르겠는데, 하이버네이트가 내부 로직을 최적화 하지 못한 것으로 추정됩니다.
아마 다음과 같이 내부에서 구분해서 사용할 듯 합니다.
//이 부분은 프록시 관리를 위해 필요한 데이터
members0_.TEAM_ID as team_id4_0_0_,
members0_.MEMBER_ID as member_i1_0_0_,
//이 부분은 순수한 Member를 구성하는 데이터
members0_.MEMBER_ID as member_i1_0_1_,
members0_.age as age2_0_1_,
members0_.name as name3_0_1_,
members0_.TEAM_ID as team_id4_0_1_
방금 말씀 드린 내용은 추정이어서, 관련해서 혹시 아는 분 있으면 답변 꼭 부탁드립니다.
(저도 사실 궁금하네요^^)
빠른 답변 감사합니다! 저도 다시 한번 찾아보겠습니다.