Spring JPA ) No converter found capable of converting from type ERROR
Spring Boot 기반 Rest Api를 작성하는 프로젝트에서 JPA를 사용하여 빠른 쿼리를 작성하는 일이
많아지면서, 다양하게 클래스를 정의하여 요청에 응답하다가
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.web.blog.dto.post.PostidandviewcntWrapperclass]
이런형식의 jpa repository에 있는 데이터를 내가 정의한 WrapperClass에 Mapping하지 못하는
문제가 발생하였다.
필자는 특정 정보끼리 합칠때 WrapperClass를 따로 정의하여 처리하는 편인데,
@Entity
@Table(name = "viewposttable")
@Data
@IdClass(viewCompositeKey.class)
@NoArgsConstructor
@AllArgsConstructor
public class view {
@Id
private int postid;
@Id
private LocalDateTime viewdate;
private String useremail;
private String username;
}
이러한 View DTO에서 postid와 postid의 합으로 정렬된 Group By postid Order By COUNT(Postid)의 정보를 담는
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class PostidandviewcntWrapperclass {
private int postid;
private int viewcnt;
}
이러한 WrapperClass를 정의하여 처리하고자 한다.
@Query(value = "SELECT v.postid AS postid,COUNT(v.postid) AS viewcnt
FROM viewposttable AS v GROUP BY v.postid
ORDER BY COUNT(v.postid) DESC ", nativeQuery = true)
List<PostidandviewcntWrapperclass> findPostidAndViewCntByTime();
적절한 Alias를 주고 해결하려했지만.. No converter found capable of converting from type
의 에러가 발생한다. 이유는 2개이상의 Object 배열을 클래스에서 뽑아올때 Mapping에 대한 정보가 없기때문에
변환이 되지않는다..
내가 참조한 자료는
https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions
Customizing the Result of JPA Queries with Aggregation Functions | Baeldung
Spring Data JPA has some useful tricks for mapping the results of aggregation queries to custom objects, rather than the default object arrays.
www.baeldung.com
https://docs.oracle.com/cd/E12839_01/apirefs.1111/e13946/ejb3_langref.html#ejb3_langref_constructor
10.2. JPQL Language Reference
The SELECT clause denotes the query result. More than one value may be returned from the SELECT clause of a query. The SELECT clause may contain one or more of the following elements: a single range variable or identification variable that ranges over an e
docs.oracle.com
위 두 글을 참조하여 해결하였다. 방법은 Spring JPA Projection으로
내가 정의한 인터페이스를 기준으로 적절한 데이터만 가져오는것을 이용하여 Repository에 있는 반환값에 매핑시켜주는것이다.
사용방법은 기존의 WrapperClass를 내가 필요한 정보만가진 interface로 정의하자
public interface PostidandviewcntProjectionInterface {
Integer getPostid();
Integer getViewcnt();
}
postid와 정렬되어 집계함수를 통과한 viewcnt를 얻어오기위한 두개의 getter를 적어주자.
이러한 Interface의 정의는 실제 두개의 int 형자료가있는 class처럼 사용이 가능하게된다.
@Query(value = "SELECT v.postid AS postid,COUNT(v.postid) AS viewcnt
FROM viewposttable AS v GROUP BY v.postid
ORDER BY COUNT(v.postid) DESC ", nativeQuery = true)
List<PostidandviewcntProjectionInterface> findPostidAndViewCntByTime();
또한 아까의 쿼리 중 리턴되는 리스트의 자료형식을 미리 선언한 인터페이스로 변환해준다면...

이번에는 Mapping이 잘되어서 가져오게 된다. : )
+ )
JPQL Constructor Expressions 이라고
SELECT NEW com.company.PublisherInfo(pub.id, pub.revenue, mag.price)
FROM Publisher pub JOIN pub.magazines mag WHERE mag.price > 5.00
이러첨 query문 안에서 특정 POJO의 경로를 지정해두고 생성하면서 리턴받는 방법도 있다..!