아래와 같은 엔티티의 조회 시도를 하려고 한다. select 문을 날리면 해당 엔티티의 속성들이 모두 조회가 될 것이다.
속성들이 이보다 더 많다면 아마 성능에 문제가 되지 않을까 싶다.
그래서 해당 속성만 뽑아내려고 시도 해봤다.
public class Post {
private Long id;
private String userName;
private String title;
private String description;
private LocalDateTime createDateTime;
private LocalDateTime updateDateTime;
}
당연히 받는 타입은 PostDto로 title 과 description 만 받게 해 놓았다.
@Query("select p.title, p.description " +
"from Post p " +
"where p.userName =:userName")
List<PostDto> findByName(@Param("userName") String userName);
데이터가 mapping이 제대로 되지 않아 아래와 같은 에러가 발생한다.
상속한 JpaRepository의 제네릭 타입인 Post 타입에 대한 mapping이 되어야 한다.
에러를 찾아 본 결과 jpa projections 으로 해결을 해야했다.
참조 : https://www.baeldung.com/spring-data-jpa-projections
dto 클래스 활용
jpql 을 작성할 때 해당 dto의 new 인스턴스를 사용하여 쿼리를 동작하게 한다.
@Query("select new " +
"com.study.boardsystem.web.dto.PostDto(p.title, p.description) " +
"from Post p " +
"where p.userName =:userName")
List<PostView> findByName(@Param("userName") String userName);
이때 해당 dto 의 생성자를 사용하여 mapping을 한다. 생성자의 매개변수 이름이 루트 엔티티 클래스의 속성과 일치해야 한다.
인터페이스 활용
루트 엔티티 속성의 getter 메서드 명과 같게 생성한다.
public interface PostView {
public String getTitle();
public String getDescription();
}
다음으로 jpql 을 작성한다. alias로 루트 엔티티와 mapping 되는 정보를 명시 해줘야 한다.
@Query("select p.title as title, p.description as description " +
"from Post p " +
"where p.userName =:userName")
List<PostView> findByName(@Param("userName") String userName);
런타임에 PostView 타입의 프록시 인스턴스를 생성하고 여기에 정의된 메서드를 호출하여 실제 타겟 객체에 전파하게 된다.
참조: https://realrain.net/post/spring-projection/
인터페이스는 Projection을 할 때에만 사용하고 dto 클래스는 언제든 데이터를 옮길 때 사용가능 하니 dto 클래스를 사용하여 인스턴스를 생성하는 것이 좋을 것 같다라는 생각이 든다.
'JPA' 카테고리의 다른 글
[Jpa] Transaction Propagation (0) | 2022.08.06 |
---|---|
[Jpa] Transaction Scope and Isolation (0) | 2022.08.05 |
[Jpa] Deprecated 된 getById() 대안 getReferenceById() (0) | 2022.08.02 |
[Jpa] Dirty Checking (0) | 2022.07.19 |
[Spring JPA] 트랜잭션은 언체크, 체크 예외에 대해 어떻게 커밋과 롤백을 처리할까? (1) | 2022.05.18 |
[Spring JPA] CASCADE 는 무엇일까? (0) | 2022.05.15 |
[Spring JPA] N + 1의 문제점이 무엇이고 어떻게 해결 해야할까? (0) | 2022.05.15 |
[Spring JPA] 프록시 객체는 어떻게 동작할까? (0) | 2022.05.12 |