본문 바로가기
Java/스프링 Data JPA

[JPQL] 일부 컬럼 값만 가져올 때 주의사항 Interface Projection

by 하이방가루 2024. 4. 8.
728x90
반응형

TL; DL

스프링 부트 1.5 와 스프링 부트 2.7 에서의 결과 값 매핑 방식이 다르다.

스프링 부트 1.5

순서대로 매핑 => 컬럼 순서와 메서드 선언 순서가 맞아야 함.

 

스프링 부트 2.7

컬럼명 매핑 => 컬럼명과 메서드명 규칙이 맞아야 함.

 

스프링 부트 1.5

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
	@Query("SELECT m.username, m.name FROM MEMBER m")
	List<MemberSimpleMapping> findAll();
}

 

위와 같이 Username 과 이름만 가져오려고 할 때

 

public interface MemberSimpleMapping {
	String getUsername();
    String getName();
}

 

이와 같이 인터페이스를 만든다면 아래와 같이 정상적으로 동작할 것이다.

 

[{"username":"test1","name":"홍길동"}]

 

요약에서 스프링 부트 1.5 가 순서대로 매핑한다고 하였다. 무슨 말일까?

 

public interface MemberSimpleMapping {
	String getName();
    String getUsername();
}

 

만약 실수로 인터페이스에 메서드 선언을 아래와 같이 하였다고 가정하자.

그렇다면 어떤 결과를 받게 될까?

 

[{"name":"test1","username":"홍길동"}]

 

이와 같이 키와 값이 안 맞게 된다.

 

스프링 부트 2.7

스프링 부트 1.5 에서는 순서대로 매핑함으로 인해서 메서드를 잘못된 순서로 입력하거나 개발 중 쿼리 변경으로 컬럼명 순서가 바뀌면 결과값의 키와 값이 잘못 매칭되는 문제가 있었다.

이러한 문제를 해결하기 위해서 인지 스프링 부트 2.7 에서는 컬럼명 매핑을 하는 것으로 보인다.

 

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
	@Query("SELECT m.username, m.name FROM MEMBER m")
	List<MemberSimpleMapping> findAll();
}

 

public interface MemberSimpleMapping {
	String getUsername();
    String getName();
}

 

위와 같이 스프링 부트 1.5 와 마찬가지로 매핑을 시도 하였다. 결과는 어떨까?

 

[{"username":null,"name":null}]

 

어떻게 된 것일까? 생성된 sql을 보면 알 수 있다.

 

select
        member0_.user_name as col_0_0_,
        member0_.name as col_1_0_,        
    from
        member member0_

 

생성된 sql을 보면 컬럼명이 col_0_0_ 와 col_1_0_ 으로 바뀌는 것을 알 수 있다.

따라서 다음과 같이 JPQL 쿼리를 작성해 주어야 한다.

 

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
	@Query("SELECT m.username AS username, m.name AS name FROM MEMBER m")
	List<MemberSimpleMapping> findAll();
}

 

AS 명령어로 해당 컬럼이 무엇인지 알려주어 제대로된 키에 값이 매핑되는 것을 볼 수 있다.

 

[{"username":"test1","name":"홍길동"}]

 

728x90
반응형

댓글