Skip to content

returnType must not be null! when working with projections #2036

@stroem2

Description

@stroem2

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions