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

이용우님의 프로필 이미지
이용우

작성한 질문수

실전! 스프링 데이터 JPA

네이티브 쿼리

GeneratedValue 공유 및 left join 질문

작성

·

304

0

안녕하세요! 유익한 강의 잘 보고 있습니다.

Native Query 테스트하는 중에 궁금한 점이 있어서 질문드립니다.

 

  1. @GeneratedValue 는 다른 Entity 끼리 공유하는건가요? Team을 2개 생성하고 Member를 생성하는데 아래 테스트 코드에서 보면 Member의 GeneratedValue 값이 1이 아니라 3부터 시작합니다.

  2. NativeQuery에서 left join을 할 때 join 조건을 주고 싶은데 Team entity의 name은 어떻게 접근해야 할까요?
     
    @Query(value = "select m.member_id as id, m.name as name, t.name as teamName from member m left join team t ", nativeQuery = true, countQuery = "select count(*) from member")

    이 쿼리를 쓰면 full join이 되서 12개의 row가 검색됩니다. 
    on 조건이나 where 절에서 m.teamName = t.name 의 조건을 주고 싶으면 m.teamName 이라는 값을 어떻게 가져와야 하나요 ?

  3. createdDate, updatedDate를 BaseEntity로 분리하면 @ToString(of = "createdDate, updatedDate") 에서 사용할 수 없는건가요 ?

 

public class Member extends BaseEntity {
    @Id@GeneratedValue
    @Column(name = "member_id")
    private Long id;
    private String name;
    private String sex;
    private Integer age;
    private String city;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id")
    private Team team;
    
    public Member(String name, String sex, Integer age, String city, Team team) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.city = city;
        if(team != null)
            changeTeam(team);
    }
    
    // 양방향 연관관계 한번에 처리(연관관계 편의 메소드)
    public void changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this);
    }
}
public class Team {

    @Id @GeneratedValue
    @Column(name = "team_id")
    private Long id;
    
    @NonNull
    private String name;

    @OneToMany(mappedBy = "team")
    List<Member> members = new ArrayList<>();
}
         @Test
	public void nativeQuery() {
		Team teamA = new Team("teamA");
		Team teamB = new Team("teamB");

		teamRepository.save(teamA);
		teamRepository.save(teamB);

		memberRepository.save(new Member("1", "남자", 18, "서울", teamA));
		memberRepository.save(new Member("2", "남자", 19, "경기", teamA));
		memberRepository.save(new Member("3", "여자", 20, "부산", teamB));
		memberRepository.save(new Member("4", "여자", 21, "울산", teamB));
		memberRepository.save(new Member("5", "남자", 22, "포항", teamA));
		memberRepository.save(new Member("6", "여자", 23, "전주", teamA));

        Member selectedMember = memberRepository.findNativeQueryByName("2");
		assertThat(selectedMember.getName()).isEqualTo("2");

		Page<MemberProjection> page = memberRepository.findByProjection(PageRequest.of(0, 20)); 
		List<MemberProjection> content = page.getContent();
		System.out.println("===============================");
		teamRepository.findAll().forEach(System.out::println);
		System.out.println("===============================");
		memberRepository.findAll().forEach(System.out::println);
		System.out.println("===============================");
		for(MemberProjection mp : content){
			System.out.println("[ id = " + mp.getId() + ", name = " + mp.getName() + ", teamName = " + mp.getTeamName() + "]");
		}
	}

답변 2

0

이용우님의 프로필 이미지
이용우
질문자

안녕하세요~ 답변 감사합니다!

 

2번 같은 경우엔 아래 쿼리로 해결했습니다.

select m.member_id as id, m.name as name, t.name as teamName from member m left join team t where m.team_id = t.team_id

 

Member Entity 안에 Team이 객체 형태로 존재하고 있어서

쿼리 내에서 접근할 때 Member 안에 있는 Team 객체의 id나 name을 어떻게 접근해야하나 고민했었는데

이미 PK가 참조되어 있기 때문에 team_id로 연결하면 되는 문제였습니다 :)

0

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

안녕하세요. 이용우님

1. @GeneratedValue 는 다른 Entity 끼리 공유하는건가요? Team을 2개 생성하고 Member를 생성하는데 아래 테스트 코드에서 보면 Member의 GeneratedValue 값이 1이 아니라 3부터 시작합니다.

-> 설정을 추가해서 각각 다른 키를 사용하는 것이 가능합니다. 실무에서는 보통 이를 분리합니다. JPA 기본편의 키 생성을 참고해주세요.

 

2. NativeQuery에서 left join을 할 때 join 조건을 주고 싶은데 Team entity의 name은 어떻게 접근해야 할까요?

 -> 네이티브 쿼리이기 때문에 엔티티와 무관합니다. SQL 문법을 그대로 사용하시면 됩니다. SQL 문법을 학습해주세요.

3. createdDate, updatedDate를 BaseEntity로 분리하면 @ToString(of = "createdDate, updatedDate") 에서 사용할 수 없는건가요 ?

-> 이 부분은 저도 정확히 기억이 나지 않네요. 롬복에서 상속 관련된 내용 같은데, 아시는 분 있으면 답변 부탁드립니다.

감사합니다.

이용우님의 프로필 이미지
이용우

작성한 질문수

질문하기