인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

이민재님의 프로필 이미지
이민재

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

다대일 [N:1]

다대일 양방향 질문입니다.

작성

·

391

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_ 

방금 말씀 드린 내용은 추정이어서, 관련해서 혹시 아는 분 있으면 답변 꼭 부탁드립니다.

(저도 사실 궁금하네요^^)

이민재님의 프로필 이미지
이민재
질문자

빠른 답변 감사합니다! 저도 다시 한번 찾아보겠습니다.

2

김영한님의 프로필 이미지
김영한
지식공유자

삭제된 글입니다

이민재님의 프로필 이미지
이민재
질문자

메일 드렸습니다!

이민재님의 프로필 이미지
이민재

작성한 질문수

질문하기