
@Query(value = "select NEW com.example.demo.dto.CustomerDTO(c.id, c.age, c.sex, c.products) from Customer c")
List<CustomerDTO> findAllCustomer();
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List com.example.demo.repository.CustomerRepository.findAllCustomer(); Reason: Validation failed for query for method public abstract java.util.List com.example.demo.repository.CustomerRepository.findAllCustomer()!; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.example.demo.repository.CustomerRepository.findAllCustomer()!
위의 에러 문구에 집중을 해보자.
현재 CustomerDTO의 생성자는 long, int, java.lang.String, Long 타입의 Collection 타입을 기대하고 있다.
이 때 내가 CustomerDTO의 생성자 인자로 넘겨주는 것은 Customer.id, Customer.age, Customer.sex, Customer.products이며,
이들의 각각 타입은 long, int, String, Product 타입의 Collection이다.
@Query(value = "select NEW com.example.demo.dto.CustomerDTO(c.id, c.age, c.sex, p.id) from Customer c join c.products p")
List<CustomerDTO> findAllCustomer();
이를 통해 현재 컬렉션의 타입이 일치하지 않아서 생긴 문제라는 것을 알 수 있다.
이렇게 위와 같이 컬렉션의 타입에 맞는 인자를 넣어줘도 되고, 생성자의 컬렉션 타입을 애초에 Product 타입으로 변경해도 괜찮다.
아래와 같이 코드를 변경하면, 정상적으로 불러온다.
@Query(value = "select NEW com.example.demo.dto.CustomerDTO(c) from Customer c")
List<CustomerDTO> findAllCustomer();
@Getter
@Setter
@NoArgsConstructor
public class CustomerDTO {
private Long id;
private int age;
private String sex;
private List<Product> products;
public CustomerDTO(Customer customer) {
this.id = customer.getId();
this.age = customer.getAge();
this.sex = customer.getSex();
this.products = getProducts();
}
}