简体   繁体   中英

spring-data-couchbase error while finding all documents with PageRequest

Using Spring Data Couchbase I created a very simple repository

public interface UserDao extends PagingAndSortingRepository<User, String>

This should allow me to execute a paged findAll as follows:

Page<User> userResult = repo.findAll(new PageRequest(1, 20));

However the the following is always thrown:

Exception in thread "main" java.lang.IllegalStateException: Unknown query param: Page request [number: 1, size 20, sort: null]
at org.springframework.data.couchbase.repository.query.ViewBasedCouchbaseQuery.execute(ViewBasedCouchbaseQuery.java:47)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:337)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.couchbase.repository.support.ViewPostProcessor$ViewInterceptor.invoke(ViewPostProcessor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at $Proxy14.findAll(Unknown Source)
at com.polycom.cloudAxis.proxymanagement.model.Main.main(Main.java:41)

This doesn't happen if I create a Query and use the skip/limit/startKeyDocId, but would like to use PagingAndSortingRepository if possible.

Any idea what could be wrong? Thanks for all friendly help :)

i also had this same issue, here was the approach i took. its actually a very small change to the core implementation (which currently only support Query object types), essentially all I did was add another instance of check:

 if (param instanceof Query) {
            query = (Query) param;
        } else if (param instanceof Pageable) {
            pageable = (Pageable) param;
        }

then added the logic for paging here, its been working so far but i havent fully vetted it so any comments from the community would be appreciated.

 if (pageable != null) {

        CouchbaseClient client = operations.getCouchbaseClient();
        View view = client.getView(designDocName(), viewName());

        // Paginator p = new Paginator(client, view, query,
        // pageable.getPageSize());
        Paginator paginator = client.paginatedQuery(view, query, pageable.getPageSize());
        // now we need to goto the start point
        ViewResponse viewResponse = null;
        // views are 0 base
        int i = 0;
        while (paginator.hasNext()) {
            viewResponse = paginator.next();
            if (pageable.getPageNumber() == i++) {
                LOGGER.debug("Found the response for this page: {} ", i);
                break;
            }
        }

        if (viewResponse == null) {
            LOGGER.debug("no view response so leaving now");
            return null;
        }
        Class<?> type = method.getEntityInformation().getJavaType();

        final List result = new ArrayList(viewResponse.size());
        for (final ViewRow row : viewResponse) {
            result.add(operations.findById(row.getId(), type));
        }
        return result;

    } 

To get this wired up i had to do some things i didnt want to :D, i wanted to just override one method however to get to it required me to override many other things, so i ended up copying a little bit of code, ideally i would like to get this added as part of https://jira.spring.io/browse/DATACOUCH-93

And the whole impl here:

public class DCORepositoryFactory extends CouchbaseRepositoryFactory {

CouchbaseOperations                                                                 couchbaseOperations;
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> mappingContext;

public DCORepositoryFactory(CouchbaseOperations couchbaseOperations) {
    super(couchbaseOperations);
    mappingContext = couchbaseOperations.getConverter().getMappingContext();
    this.couchbaseOperations = couchbaseOperations;
}

@Override
protected Object getTargetRepository(RepositoryMetadata metadata) {
    // TODO Auto-generated method stub
    CouchbaseEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
    final DCORepository simpleCouchbaseRepository = new DCORepository(entityInformation, couchbaseOperations);

    simpleCouchbaseRepository.setViewMetadataProvider(ViewPostProcessor.INSTANCE.getViewMetadataProvider());
    return simpleCouchbaseRepository;
}

@Override
protected QueryLookupStrategy getQueryLookupStrategy(QueryLookupStrategy.Key key) {
    return new CouchbaseQueryLookupStrategy();
}

/**
 * Currently, only views are supported. N1QL support to be added.
 */
private class CouchbaseQueryLookupStrategy implements QueryLookupStrategy {
    @Override
    public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
        CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method, metadata, mappingContext);
        return new PagingViewBasedCouchbaseQuery(queryMethod, couchbaseOperations);
    }
}

private static class PagingViewBasedCouchbaseQuery extends ViewBasedCouchbaseQuery {

    private static final org.slf4j.Logger   LOGGER  = org.slf4j.LoggerFactory
                                                            .getLogger(DCORepositoryFactory.PagingViewBasedCouchbaseQuery.class);

    private CouchbaseOperations             operations;
    private CouchbaseQueryMethod            method;

    public PagingViewBasedCouchbaseQuery(CouchbaseQueryMethod method, CouchbaseOperations operations) {
        super(method, operations);
        this.operations = operations;
        this.method = method;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.couchbase.repository.query.
     * ViewBasedCouchbaseQuery#execute(java.lang.Object[]) added the ability
     * to support paging
     */
    @Override
    public Object execute(Object[] runtimeParams) {
        Query query = null;
        Pageable pageable = null;
        for (Object param : runtimeParams) {
            if (param instanceof Query) {
                query = (Query) param;
            } else if (param instanceof Pageable) {
                pageable = (Pageable) param;
            } else {
                throw new IllegalStateException(
                        "Unknown query param: (btw null is also not allowed and pagable cannot be null) " + param);
            }
        }

        if (query == null) {
            query = new Query();
        }
        query.setReduce(false);
        if (pageable != null) {

            CouchbaseClient client = operations.getCouchbaseClient();
            View view = client.getView(designDocName(), viewName());

            // Paginator p = new Paginator(client, view, query,
            // pageable.getPageSize());
            Paginator paginator = client.paginatedQuery(view, query, pageable.getPageSize());
            // now we need to goto the start point
            ViewResponse viewResponse = null;
            // views are 0 base
            int i = 0;
            while (paginator.hasNext()) {
                viewResponse = paginator.next();
                if (pageable.getPageNumber() == i++) {
                    LOGGER.debug("Found the response for this page: {} ", i);
                    break;
                }
            }

            if (viewResponse == null) {
                LOGGER.debug("no view response so leaving now");
                return null;
            }
            Class<?> type = method.getEntityInformation().getJavaType();

            final List result = new ArrayList(viewResponse.size());
            for (final ViewRow row : viewResponse) {
                result.add(operations.findById(row.getId(), type));
            }
            return result;

        } else {
            return operations.findByView(designDocName(), viewName(), query, method.getEntityInformation()
                    .getJavaType());
        }
    }

    /**
     * Returns the best-guess design document name.
     *
     * @return the design document name.
     */
    private String designDocName() {
        if (method.hasViewAnnotation()) {
            return method.getViewAnnotation().designDocument();
        } else {
            return StringUtils.uncapitalize(method.getEntityInformation().getJavaType().getSimpleName());
        }
    }

    /**
     * Returns the best-guess view name.
     *
     * @return the view name.
     */
    private String viewName() {
        if (method.hasViewAnnotation()) {
            return method.getViewAnnotation().viewName();
        } else {
            return StringUtils.uncapitalize(method.getName().replaceFirst("find", ""));
        }
    }
}

@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata repositoryMetadata) {
    return DCORepository.class;
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM