공부공간

Spring JPA ) No converter found capable of converting from type ERROR 본문

Spring/JPA

Spring JPA ) No converter found capable of converting from type ERROR

개발자가될수있을까? 2020. 8. 13. 00:38

 

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의 경로를 지정해두고 생성하면서 리턴받는 방법도 있다..!

 

Comments