Open
Description
Hello, I am migrating from Spring Boot 2.2 (Spring Couchbase 3.x) to Spring Boot 2.7 (Spring Couchbase 4.x) and I am getting this exception:
java.lang.IllegalArgumentException: returnType must not be null!
at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.3.31.jar:5.3.31]
at org.springframework.data.couchbase.core.ExecutableFindByQueryOperationSupport$ExecutableFindByQuerySupport.as(ExecutableFindByQueryOperationSupport.java:124) ~[spring-data-couchbase-4.4.18.jar:4.4.18]
at org.springframework.data.couchbase.repository.query.AbstractCouchbaseQuery.lambda$getExecutionToWrap$1(AbstractCouchbaseQuery.java:126) ~[spring-data-couchbase-4.4.18.jar:4.4.18]
at org.springframework.data.couchbase.repository.query.CouchbaseQueryExecution$ResultProcessingExecution.execute(CouchbaseQueryExecution.java:84) ~[spring-data-couchbase-4.4.18.jar:4.4.18]
at org.springframework.data.couchbase.repository.query.AbstractCouchbaseQuery.doExecute(AbstractCouchbaseQuery.java:95) ~[spring-data-couchbase-4.4.18.jar:4.4.18]
at org.springframework.data.couchbase.repository.query.AbstractCouchbaseQueryBase.execute(AbstractCouchbaseQueryBase.java:133) ~[spring-data-couchbase-4.4.18.jar:4.4.18]
at org.springframework.data.couchbase.repository.query.AbstractCouchbaseQueryBase.execute(AbstractCouchbaseQueryBase.java:113) ~[spring-data-couchbase-4.4.18.jar:4.4.18]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.7.18.jar:2.7.18]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.7.18.jar:2.7.18]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:160) ~[spring-data-commons-2.7.18.jar:2.7.18]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:139) ~[spring-data-commons-2.7.18.jar:2.7.18]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.31.jar:5.3.31]
at org.springframework.data.couchbase.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:141) ~[spring-data-couchbase-4.4.18.jar:4.4.18]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.31.jar:5.3.31]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.31.jar:5.3.31]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.31.jar:5.3.31]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241) ~[spring-aop-5.3.31.jar:5.3.31]
at com.sun.proxy.$Proxy223.getDetails(Unknown Source) ~[?:?]
at com.example.UserController.getDetails(UserController.java:32) ~[classes/:?]
User Document:
@EqualsAndHashCode(callSuper = true)
@Document
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@Valid
public class User extends ParentUser {
private String firstName;
private String lastName;
private String address;
private boolean isTest;
}
Projection Interface:
public final class Projections {
@Projection(name = "names", types = {User.class})
interface Names {
String getFirstName();
String getLastName();
}
}
User Repository
public interface UserRepository extends PagingAndSortingRepository<User, String> {
@Query("""
#{#n1ql.selectEntity} WHERE #{#n1ql.filter}
AND isTest = true
"""
)
List<Projections.Names> getDetails(@Param("isTest") boolean isTest);
}
User Controller
@RestController
@RequestMapping(value = "/users")
@RequiredArgsConstructor
public class UserController {
private final UserRepository repository;
@GetMapping(value = {"/find/test"}, produces = APPLICATION_JSON_VALUE)
public Projections.Names getDetails(@RequestParam("isTest") final boolean isTest) {
return repository.getDetails(isTest);
}
Can projections still be used?