DynamoDB не может найти sortKey в запросе - PullRequest
0 голосов
/ 28 ноября 2018

Я использую Spring boot и DynamoDB с подкачкой, где мне нужно несколько типов запросов:

  • OrganizationID (HashKey "HK") и PersonId (RangeKey "RK") -> возвращает один
  • PersonID (RK) -> возвращает организации, с которыми связан человек
  • OrganizationID (HK) и SortKey (RK) -> возвращает сотрудников в организации, и нумерация страниц включена.

Классы сущностей и репозитория находятся здесь:

@DynamoDBTable(tableName = "organizationPersons")
public class OrganizationPersonsEntity {

    @Id
    private OrganizationPersonsEntityId id;

    private UUID organizationId;
    private UUID personId;
    private String type;
    private String sortKey;
    private String personSortName;

    public OrganizationPersonsEntity(){

    }

    public OrganizationPersonsEntity(UUID orgnizationId, UUID personId) {
        setOrganizationId(orgnizationId);
        setPersonId(personId);
    }


    public OrganizationPersonsEntity(UUID orgnizationId, UUID personId, String type, String personSortName) {
        setOrganizationId(orgnizationId);
        setPersonId(personId);
        this.type = type;
        this.personSortName = personSortName;
    }

    @DynamoDBHashKey
    @DynamoDBIndexHashKey(globalSecondaryIndexName = "sortIndex")
    public UUID getOrganizationId() {
        return id != null ? id.getOrganizationId() : null;
    }

    public void setOrganizationId(UUID orgnizationId) {
        if (id == null) {
            id = new OrganizationPersonsEntityId();
        }
        this.id.setOrganizationId(orgnizationId);
    }

    @DynamoDBRangeKey
    @DynamoDBIndexHashKey(globalSecondaryIndexName = "personIndex")
    public UUID getPersonId() {
        return id != null ? id.getPersonId(): null;
    }

    public void setPersonId(UUID personId) {
        if (id == null) {
            id = new OrganizationPersonsEntityId();
        }
        this.id.setPersonId(personId);
    }

    @DynamoDBAttribute
    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @DynamoDBIndexRangeKey(globalSecondaryIndexNames = {"sortIndex"})
    public String getSortKey() {
        if (sortKey == null) {
            return personSortName + "-" + id.organizationId + "-" + id.personId;
        } else {
            return sortKey;
        }
    }

    public void setSortKey(String sortKey) {
        this.sortKey = sortKey;
    }

    public static class OrganizationPersonsEntityId implements Serializable {
        private static final long serialVersionUID = 1L;

        private UUID organizationId;
        private UUID personId;

        public OrganizationPersonsEntityId() {
        }

        public OrganizationPersonsEntityId(UUID organizationId, UUID personId) {
            this.organizationId = organizationId;
            this.personId = personId;
        }

        @DynamoDBHashKey
        public UUID getOrganizationId() {
            return organizationId;
        }

        public void setOrganizationId(UUID id) {
            this.organizationId = id;
        }

        @DynamoDBRangeKey
        public UUID getPersonId() {
            return personId;
        }

        public void setPersonId(UUID personId) {
            this.personId = personId;
        }
    }
}

И

@Repository
public interface OrganizationPersonsRepository extends 
DynamoDBPagingAndSortingRepository<OrganizationPersonsEntity, UUID> {

    Optional<List<OrganizationPersonsEntity>> findAllByPersonId(UUID personId);

    Page<OrganizationPersonsEntity> findAllByOrganizationId(UUID organizationId, Pageable pageable);

    Page<OrganizationPersonsEntity> findAllByOrganizationIdAndSortKeyBetween(UUID organizationId, String after, String before, Pageable pageRequest);

    Page<OrganizationPersonsEntity> findAllByOrganizationIdAndSortKeyGreaterThanEqual(UUID organizationId, String after, Pageable pageRequest);

    Page<OrganizationPersonsEntity> findAllByOrganizationIdAndSortKeyLessThanEqual(UUID organizationId, String before, Pageable pageRequest);

    OrganizationPersonsEntity findByOrganizationIdAndPersonId(UUID organizationId, UUID personId);

    default RepositoryPagingQuery<OrganizationPersonsEntity> findAllByOrganizationIdQuery(UUID organization) {
        return (after, before, limit, ascending) -> {
            PageRequest pageRequest = PageRequest.of(0, limit, ascending ? Sort.Direction.ASC : Sort.Direction.DESC, "sortKey");
            if (after != null && before != null) {
                return findAllByOrganizationIdAndSortKeyBetween(organization, after, before, pageRequest).getContent();
            } else if (after != null) {
                return findAllByOrganizationIdAndSortKeyGreaterThanEqual(organization, after, pageRequest).getContent();
            } else if (before != null) {
                return findAllByOrganizationIdAndSortKeyLessThanEqual(organization, before, pageRequest).getContent();
            } else {
                return findAllByOrganizationId(organization, pageRequest).getContent();
            }
        };
    }
}

Теперь, если я попытаюсь запросить findAllByOrganizationId (UIID organizationId, Pageable pageable), используя следующую строку:

PageInfo<UUID> page = RepositoryPaginationUtil.makePageFromRepository(organizationPersonsRepository.findAllByOrganizationIdQuery(uuid),
                e -> e.getSortKey(),
                e -> e.getPersonId(),
                first, after, last, before);
        final List<ResearcherDTO> researcherDTOS = page.getContents().stream().map(uuid1 -> getPerson(uuid, uuid1)).collect(Collectors.toList());

Я получаю сообщение об ошибке, что его можно отсортировать только по personId, даже если "sortKey" определен как IndexRangeKey.

java.lang.UnsupportedOperationException: Sorting only possible by [personId] for the criteria specified
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.applySortIfSpecified(AbstractDynamoDBQueryCriteria.java:157)
    at org.socialsignin.spring.data.dynamodb.repository.query.DynamoDBEntityWithHashAndRangeKeyCriteria.buildQueryExpression(DynamoDBEntityWithHashAndRangeKeyCriteria.java:186)
    at org.socialsignin.spring.data.dynamodb.repository.query.DynamoDBEntityWithHashAndRangeKeyCriteria.buildFinderQuery(DynamoDBEntityWithHashAndRangeKeyCriteria.java:221)
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.buildQuery(AbstractDynamoDBQueryCriteria.java:438)
    at org.socialsignin.spring.data.dynamodb.repository.query.DynamoDBQueryCreator.complete(DynamoDBQueryCreator.java:45)
    at org.socialsignin.spring.data.dynamodb.repository.query.DynamoDBQueryCreator.complete(DynamoDBQueryCreator.java:29)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:94)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:80)
    at org.socialsignin.spring.data.dynamodb.repository.query.PartTreeDynamoDBQuery.doCreateQuery(PartTreeDynamoDBQuery.java:56)
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.doCreateQueryWithPermissions(AbstractDynamoDBQuery.java:81)
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery$PagedExecution.execute(AbstractDynamoDBQuery.java:159)
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.execute(AbstractDynamoDBQuery.java:311)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:570)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:554)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy128.findAllByOrganizationId(Unknown Source)
    at com.elsevier.consoles.institutional.services.person.storage.OrganizationPersonsRepository.lambda$findAllByOrganizationIdQuery$0(OrganizationPersonsRepository.java:44)
    at com.elsevier.consoles.util.pagination.RepositoryPaginationUtil$RepositoryPager.getEdgesFromRepositoryBetween(RepositoryPaginationUtil.java:113)
    at com.elsevier.consoles.util.pagination.RepositoryPaginationUtil$RepositoryPager.getEdgesFromRepositoryWithNone(RepositoryPaginationUtil.java:108)
    at com.elsevier.consoles.util.pagination.RepositoryPaginationUtil$RepositoryPager.getEdgesFromRepository(RepositoryPaginationUtil.java:130)
    at com.elsevier.consoles.util.pagination.RepositoryPaginationUtil$RepositoryPager.makePage(RepositoryPaginationUtil.java:166)
    at com.elsevier.consoles.util.pagination.RepositoryPaginationUtil.makePageFromRepository(RepositoryPaginationUtil.java:46)
    at com.elsevier.consoles.institutional.services.person.service.StoragePersonService.getOrganizationResearchers(StoragePersonService.java:72)
    at com.elsevier.consoles.institutional.services.person.ws.PersonRestController.organizationResearchers(PersonRestController.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:84)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:176)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at io.opentracing.contrib.web.servlet.filter.TracingFilter.doFilter(TracingFilter.java:165)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748) 

Я надеюсь, что кто-то сможет помочь, спасибо вadvance.

Версии Spring boot 2.0.1.RELEASE, Maven: com.github.derjust: spring-data-dynamodb: 5.0.3, com.amazonaws: aws-java-sdk-Dynamodb: jar: 1.110,336

...