Я использую 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