QueryDSL에서 생성자 예외
java.lang.NoSuchMethodException: ...<init>()
프로젝트 도중 JPA 동적쿼리로 페이징 처리를 했어야 했기 때문에 QueryDsl을 사용해야 했습니다. 쿼리문을 쏘고 나서, 리턴 타입을 반환할 때 Entity보단 DTO가 반환되기를 원했고, 그래서 쿼리문에 필드 Projection으로 DTO를 반환하도록 했습니다. 그러던 중, 위와 같은 예외가 터졌습니다.
@Override
public Page<OrderListResponse> findAllByMemberId(Long memberId, OrderSearchCond condition, Pageable pageable) {
List<OrderListResponse> content = queryFactory
.select(fields(OrderListResponse.class,
orders.id.as("ordersId"), orders.createdDate, orders.orderItemName,
orders.totalPrice, orders.totalDeliveryPrice
))
.from(orders)
.where(orders.member.id.eq(memberId),
dateBetween(condition.getStartDate(), condition.getEndDate())
)
.orderBy(orders.createdDate.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
Long total = queryFactory
.select(orders.count())
.from(orders)
.where(orders.member.id.eq(memberId))
.fetchOne();
return new PageImpl<OrderListResponse>(content, pageable, total);
}
코드에는 별 문제가 없어 보였습니다. 그런데,
컴파일러에서 발생한 예외를 보던 중 getConstructor
가 눈에 확 보이네요. 그래서 OrderListResponse로 가보니까 아뿔사 하고 맙니다.
@Getter
@Builder
@AllArgsConstructor
public class OrderListResponse {
private Long ordersId;
private LocalDateTime createdDate;
private String orderItemName;
private int totalPrice;
private int totalDeliveryPrice;
}
바로 기본생성자를 만들지 않았던 것입니다.
Querydsl은 클래스에 기본 생성자를 필요로 하며, 인스턴스 생성 시 기본 생성자를 호출합니다. 그러나 생성자가 없거나 매개변수가 있는 생성자만 있는 경우, Querydsl에서는 인스턴스를 생성할 수 없으므로 예외가 발생합니다.
@ModelAttribute
로 프론트의 값을 컨트롤러에서 바인딩 할 때 기본생성자를 두면 null로 와서, 기본 생성자를 만들지 않았던 습관으로 생겼던 예외였습니다.
스프링 ModelAttribute 이해하기
https://jaykaybaek.tistory.com/15
'Spring Data' 카테고리의 다른 글
HibernateException 예외 해결 - JPA 연관관계 매핑에서 발생한 문제 해결 방법 (0) | 2023.02.25 |
---|---|
Entity는 기본형 타입과 래퍼클래스 중 어떤 것을 사용하는가? (0) | 2023.01.29 |