▼ Backend/└ QueryDsl

Spring Boot | No constructor found for class.. with parameters

Valar 2022. 5. 12. 11:20
반응형

▶︎  로그

No constructor found for class com.admin.domain.board.Board$Response with parameters: [class java.lang.Long, class java.lang.String, class java.lang.String, class java.time.LocalDateTime]

 

QueryDsl을 사용하다 보면  필요한 칼럼만 조회하거나 서브 쿼리를 이용하여 칼럼을 추가할 때 Projections.constructor에 조회결과를 리턴 받을 클래스를 지정하는데 해당 클래스의 생성자에 조회 결과의 컬럼 리턴 타입과 리턴 개수가 정확해야 한다.

 

Projections.constructor(Board.Response.class)

 

예시)

조회할 때 board의 4개의 칼럼의 타입은 순서대로 id(Long), type(String), title(String), registerTime(LocalDateTime)이다.

 

private QBoard board = QBoard.board;

jpaQueryFactory
    .select(Projections.constructor(Board.Response.class,
            board.id,
            board.type,
            board.title,
            board.registerTime
    ))
    .from(board)
    .fetch();

 

하지만, Projections.constructor에 지정한 Board.Response 클래스의 생성자에는 registerTime이 String으로 되어 있었다. 

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity(name = "board")
public class Board extends {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    private Long id;
    private String type;
    private String title;
    private String contents;
    private LocalDateTime registerTime;

    @Getter
    public static class Response {
        private Long id;
        private String type;
        private String title;
        private String registerTime;

        public Response(Long id, String type, String title, String registerTime) {
            this.id = id;
            this.type = type;
            this.title = title;
            this.registerTime = registerTime;
        }
    }
}

또는 리턴 받을 생성자의 매개변수 개수가 맞지 않을 경우..

public Response(Long id, String type, String title) {
    this.id = id;
    this.type = type;
    this.title = title;
}

 

아래와 같이 개수와 타입을 정확하게 명시해주거나

타입을 변경해서 사용하려 한다면 생성자 내에서 재가공하여 사용하면 된다. (주석 처리된 부분 참고)

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity(name = "board")
public class Board extends {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    private Long id;
    private String type;
    private String title;
    private String contents;
    private LocalDateTime registerTime;

    @Getter
    public static class Response {
        private Long id;
        private String type;
        private String title;
        private LocalDateTime registerTime;
	
        public Response(Long id, String type, String title, LocalDateTime registerTime) {
            this.id = id;
            this.type = type;
            this.title = title;
            this.registerTime = registerTime;
        }
//	  private String registerTime;
//        public Response(Long id, String type, String title, LocalDateTime registerTime, String registerName) {
//            this.id = id;
//            this.type = type;
//            this.title = title;
//            this.registerTime = DateUtil.toStringDateTime(registerTime);
//        }
    }
}

 

반응형