본문 바로가기
Java/JPA

@NamedNativeQuery 결과 POJO에 매핑

by TheUphill 2018. 1. 15.

@NamedNativeQuery 결과 POJO에 매핑

JPQL에 사용할수 없는 기능들이 있는데 그 중 하나가 UNION 기능이다. 이를 보완하기 위해 @NamedNatvieQuery를 이용해 Natvie 쿼리를 사용할 수 있게 지원한다.

예제

먼저 사용된 예제를 살펴보자. 추출 목적은 STUDENT 테이블과 TEACHER 테이블의 데이터를 한번에 보여주고 싶다.


@Data
@NamedNativeQuery(
        name = "Person.methodNameInRepository",
        query = "SELECT s.id, s.name, s.phone, s.address FROM STUDENT s WHERE s.class_number = (?1) " +
                "UNION " +
                "SELECT t.id, t.name, t.phone, t.address FROM TEACHER t WHERE t.class_number = (?1)",
        resultSetMapping = "personProfileMapper"
)
@SqlResultSetMapping(
        name = "personProfileMapper",
        classes = {@ConstructorResult(
                targetClass = PersonDto.class,
                columns = {
                        @ColumnResult(name = "id"),
                        @ColumnResult(name = "name"),
                        @ColumnResult(name = "phone"),
                        @ColumnResult(name = "address")
                }
        )}
)

@NamedNativeQuery 속성

  • name : 이름. 뒤에 붙는 메소드 이름(methodNameInRepository)과 @Repository 인터페이스에서 선언할 함수의 이름은 동일해야한다.
  • query : 사용할 쿼리. JPQL 문법이 아닌 각 벤더에 맞는 쿼리를 그대로 사용한다. 클래스에 선언한 Entity 속성들이 아닌 아닌 테이블이름 및 컬럼명을 사용해야한다. 여기에 입력한 쿼리 내용이 그대로 JDBC로 전달된다.
  • resultSetMapping : 쿼리 결과를 객체에 어떻게 담을지 설정하는 @SqlResultSetMapping의 이름을 명시. @SqlResultSetMapping은 아래에서 설명한다.

POJO에 쿼리 결과 바인딩

JPA 2.1 이전에는 쿼리의 결과를 반드시 엔티티(@Entity) 객체에 담아야 했다. 하지만 JPA 2.1이후로 POJO에도 객체 생성자를 이용해서 결과값을 담을 수 있다.

- @SqlResultSetMapping

쿼리 결과를 객체에 어떻게 담을지 설정

  • name : 매퍼 이름
  • classes : 결과값을 저장할 타겟 객체 관련 설정. @ContructorResult를 이용해 설정한다. (JPA 2.1에 추가된 기능)

- @ConstructorResult

쿼리 결과를 객체 생성자를 이용해 저장 (JPA 2.1에 추가)

  • targetClass : 결과를 저장할 클래스 명시
  • columns : 쿼리로 조회한 컬럼 중 객체에 바인딩할 컬럼 명시. 필수값이다! @ColumnResult를 사용해 결과를 저장할 컬럼들을 명시한다.

주의사항

위에 @ConstructorResultcolumns들을 명시할때 순서에 주의해야 한다. columns속성의 순서와 사용하고자 하는 생성자의 파라미터 갯수 및 순서가 일치해야 한다(변수명은 동일하지 않아도 된다) 그렇지 않을경우 엉뚱할 속성에 값이 바인딩 되거나 "Could not locate appropriate constructor on class" 같은 에러 메세지가 튀어나온다.

참고

https://stackoverflow.com/questions/13012584/jpa-how-to-convert-a-native-query-result-set-to-pojo-class-collection

댓글