Home [Spring] ConverterNotFoundException No converter found capable of converting from type
Post
Cancel

[Spring] ConverterNotFoundException No converter found capable of converting from type

에러 발생 상황

JPA를 활용한 nativeQuery로 DTO를 만들어 맵핑하는 과정에서 발생된 에러이다.

org.springframework.core.convert.ConverterNotFoundException No converter found capable of converting from type


Repository

1
2
3
4
5
6
7
8
9
10
@Query(value = "SELECT b.*, IFNULL(l.loan_status, '대출 가능') AS loan_status " +
"FROM books b " +
"LEFT JOIN ( " +
" SELECT book_id, IF(COUNT(*) > 0, '대출 중', '대출 가능') AS loan_status " +
" FROM loans " +
" WHERE return_date IS NULL " +
" GROUP BY book_id " +
") l ON b.book_id = l.book_id " +
"WHERE b.book_id = :bookId", nativeQuery = true)
BookLoanInfoDto findByBookWithLoanByBookId(@Param("bookId") Long bookId);

Dto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Getter
public class BookLoanInfoDto {
    private Long bookId;
    private String title;
    private String author;
    private String language;
    private String publisher;
    private LocalDateTime createdAt;
    private LocalDateTime modifiedAt;
    private String status;

    public BookLoanInfoDto(
            Long bookId,
            String title,
            String author,
            String language,
            String publisher,
            LocalDateTime createdAt,
            LocalDateTime modifiedAt,
            String status
    ) {
        this.bookId = bookId;
        this.title = title;
        this.author = author;
        this.language = language;
        this.publisher = publisher;
        this.createdAt = createdAt;
        this.modifiedAt = modifiedAt;
        this.status = status;
    }
}


해결 과정

필드명 변경

Entity에서 사용되는 칼럼명이 아닌 DB에서 사용되는 칼럼명으로 변경되어야 한다.

Dto 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Getter
public class BookLoanInfoDto {
    private Long book_id; // 변경
    private String title;
    private String author;
    private String language;
    private String publisher;
    private LocalDateTime created_at; // 변경
    private LocalDateTime modifie_at; // 변경
    private String loan_status;

    public BookLoanInfoDto(
            Long book_id, // 변경
            String title,
            String author,
            String language,
            String publisher,
            LocalDateTime created_at, // 변경
            LocalDateTime modifie_at, // 변경
            String loan_status // 변경
    ) {
        this.book_id = book_id; // 변경
        this.title = title;
        this.author = author;
        this.language = language;
        this.publisher = publisher;
        this.created_at = created_at;
        this.modified_at = modified_at;
        this.loan_status = loan_status;
    }
}

하지만 이렇게 변경하여도 여전히 같은 에러가 발생하였다.


해결

interface 생성

BookDetailView Interface 생성

1
2
3
4
5
6
7
8
9
10
11
public interface BookDetailView {
    Long getbook_id();
    Long getuser_id();
    String getTitle();
    String getAuthor();
    String getLanguage();
    String getPublisher();
    LocalDateTime getCreated_at();
    LocalDateTime getModified_at();
    String getLoan_status();
}

Repository 변경

1
2
3
4
5
6
7
8
9
10
@Query(value = "SELECT b.*, IFNULL(l.loan_status, '대출 가능') AS loan_status " +
"FROM books b " +
"LEFT JOIN ( " +
" SELECT book_id, IF(COUNT(*) > 0, '대출 중', '대출 가능') AS loan_status " +
" FROM loans " +
" WHERE return_date IS NULL " +
" GROUP BY book_id " +
") l ON b.book_id = l.book_id " +
"WHERE b.book_id = :bookId", nativeQuery = true)
BookDetailView findByBookWithLoanByBookId(@Param("bookId") Long bookId);

JPA에서 DB에 필요한 속성을 조회하는 것을 Projection 이라고 한다. ProjectionEntity 기반DTO 기반이 있는데, JPA에서 DTO 형식으로 조회 했기 때문에 interface 기반의 Projection을 사용해야 문제를 해결할 수 있다.

DTO기반으로 할시 조회를 원하는 속성들의 집합으로 get(필드명)을 사용하면 호환이 가능하다.