春季数据AWS DynamoDB存储库查找contains throws classcastException

发布于 2025-01-19 15:50:11 字数 14338 浏览 1 评论 0原文

我有一个称为组表的AWS DynamoDB表。它包含两个字段ID和成员。成员字段是字符串集。我想搜索组表并返回所有成员列表中包含指定字符串的组。

当我使用Spring Data的CRUD存储库FindbyMembersContains尝试此操作时,它将返回一个classcastException,说明Java.lang.String无法将其施加到Java.util.collection。

我还尝试使用一个字符串列表而不是字符串集,并获得相同的结果。

我正在使用AWS Java SDK DynamoDB版本1.12.192和Spring Data DynamoDB版本5.1.0。 我没有问题使用存储库来编写这些条目或通过ID阅读。

group.java

@DynamoDBTable(tableName = "GroupTable")
public class Group {

    String id;
    Set<String> members;

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @DynamoDBAttribute
    public Set<String> getMembers() {
        return members;
    }

    public void setMembers(Set<String> members) {
        this.members = members;
    }

}

grouprepository.java

@EnableScan
public interface GroupRepository extends CrudRepository<Group, String> {

    List<Group> findByMembersContaining(String member);

}

groupcontroller.java

@RestController
@RequestMapping("/group")
public class GroupController {

    private final GroupRepository groupRepository;

    public GroupController(GroupRepository groupRepository) {
        this.groupRepository = groupRepository;
    }

    @GetMapping("/test")
    public List<Group> getTestGroups() {
        String testMemberId = "SomeMemberId";
        return groupRepository.findByMembersContaining(testMemberId);
    }

}

dynamodbconfig.java

@Configuration
@EnableDynamoDBRepositories(basePackages = "com.example.dynamodbtest.repository")
public class DynamoDBConfig {

    @Value("${amazon.dynamodb.endpoint}")
    private String amazonDynamoDBEndpoint;

    @Value("${amazon.aws.accesskey}")
    private String amazonAWSAccessKey;

    @Value("${amazon.aws.secretkey}")
    private String amazonAWSSecretKey;

    private final ApplicationContext context;

    public DynamoDBConfig(ApplicationContext context) {
        this.context = context;
    }

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        AmazonDynamoDB amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());
        if (!ObjectUtils.isEmpty(amazonDynamoDBEndpoint)) {
            amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
        }
        return amazonDynamoDB;
    }

    @Bean
    public AWSCredentials amazonAWSCredentials() {
        return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
    }

    @Bean(name = "mvcHandlerMappingIntrospectorCustom")
    public HandlerMappingIntrospector mvcHandlerMappingIntrospectorCustom() {
        HandlerMappingIntrospector handlerMappingIntrospector = new HandlerMappingIntrospector();
        handlerMappingIntrospector.setApplicationContext(context);
        return handlerMappingIntrospector;
    }

}

stack stack trace

java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Collection
    at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$Vector$ToSet$1.convert(StandardTypeConverters.java:449) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$DelegateConverter.convert(DynamoDBTypeConverter.java:104) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$NullSafeConverter.convert(DynamoDBTypeConverter.java:123) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$ExtendedConverter.convert(DynamoDBTypeConverter.java:83) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.convert(DynamoDBMapperFieldModel.java:138) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.getPropertyAttributeValue(AbstractDynamoDBQueryCriteria.java:499) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.createSingleValueCondition(AbstractDynamoDBQueryCriteria.java:648) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.withSingleValueCriteria(AbstractDynamoDBQueryCriteria.java:427) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.addCriteria(AbstractDynamoDBQueryCreator.java:103) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.create(AbstractDynamoDBQueryCreator.java:74) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.create(AbstractDynamoDBQueryCreator.java:42) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:119) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.socialsignin.spring.data.dynamodb.repository.query.PartTreeDynamoDBQuery.doCreateQuery(PartTreeDynamoDBQuery.java:56) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.doCreateQueryWithPermissions(AbstractDynamoDBQuery.java:81) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery$CollectionExecution.execute(AbstractDynamoDBQuery.java:100) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.execute(AbstractDynamoDBQuery.java:311) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.18.jar:5.3.18]
    at com.sun.proxy.$Proxy69.findByMembersContaining(Unknown Source) ~[na:na]
    at com.example.dynamodbtest.controller.GroupController.getTestGroups(GroupController.java:24) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

aws dynamodb对象 组对象显示字符串SET

I have an AWS DynamoDB Table called Group Table. It contains two fields ID and Members. The members field is a String Set. I would like to search the Group Table and return all Groups where the list of members contains a specified string.

When I attempt this using Spring Data's CRUD Repository FindByMembersContains, it returns a ClassCastException stating java.lang.String cannot be cast to java.util.Collection.

I have also attempted with a String List instead of String Set and get the same results.

I am using AWS Java SDK DynamoDB version 1.12.192 and Spring Data DynamoDB version 5.1.0.
I have no issues writing these entries or reading by ID using the repository.

Group.java

@DynamoDBTable(tableName = "GroupTable")
public class Group {

    String id;
    Set<String> members;

    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @DynamoDBAttribute
    public Set<String> getMembers() {
        return members;
    }

    public void setMembers(Set<String> members) {
        this.members = members;
    }

}

GroupRepository.java

@EnableScan
public interface GroupRepository extends CrudRepository<Group, String> {

    List<Group> findByMembersContaining(String member);

}

GroupController.java

@RestController
@RequestMapping("/group")
public class GroupController {

    private final GroupRepository groupRepository;

    public GroupController(GroupRepository groupRepository) {
        this.groupRepository = groupRepository;
    }

    @GetMapping("/test")
    public List<Group> getTestGroups() {
        String testMemberId = "SomeMemberId";
        return groupRepository.findByMembersContaining(testMemberId);
    }

}

DynamoDBConfig.java

@Configuration
@EnableDynamoDBRepositories(basePackages = "com.example.dynamodbtest.repository")
public class DynamoDBConfig {

    @Value("${amazon.dynamodb.endpoint}")
    private String amazonDynamoDBEndpoint;

    @Value("${amazon.aws.accesskey}")
    private String amazonAWSAccessKey;

    @Value("${amazon.aws.secretkey}")
    private String amazonAWSSecretKey;

    private final ApplicationContext context;

    public DynamoDBConfig(ApplicationContext context) {
        this.context = context;
    }

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        AmazonDynamoDB amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());
        if (!ObjectUtils.isEmpty(amazonDynamoDBEndpoint)) {
            amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
        }
        return amazonDynamoDB;
    }

    @Bean
    public AWSCredentials amazonAWSCredentials() {
        return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
    }

    @Bean(name = "mvcHandlerMappingIntrospectorCustom")
    public HandlerMappingIntrospector mvcHandlerMappingIntrospectorCustom() {
        HandlerMappingIntrospector handlerMappingIntrospector = new HandlerMappingIntrospector();
        handlerMappingIntrospector.setApplicationContext(context);
        return handlerMappingIntrospector;
    }

}

Stack Trace

java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Collection
    at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$Vector$ToSet$1.convert(StandardTypeConverters.java:449) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$DelegateConverter.convert(DynamoDBTypeConverter.java:104) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$NullSafeConverter.convert(DynamoDBTypeConverter.java:123) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$ExtendedConverter.convert(DynamoDBTypeConverter.java:83) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.convert(DynamoDBMapperFieldModel.java:138) ~[aws-java-sdk-dynamodb-1.12.192.jar:na]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.getPropertyAttributeValue(AbstractDynamoDBQueryCriteria.java:499) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.createSingleValueCondition(AbstractDynamoDBQueryCriteria.java:648) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCriteria.withSingleValueCriteria(AbstractDynamoDBQueryCriteria.java:427) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.addCriteria(AbstractDynamoDBQueryCreator.java:103) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.create(AbstractDynamoDBQueryCreator.java:74) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQueryCreator.create(AbstractDynamoDBQueryCreator.java:42) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:119) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.socialsignin.spring.data.dynamodb.repository.query.PartTreeDynamoDBQuery.doCreateQuery(PartTreeDynamoDBQuery.java:56) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.doCreateQueryWithPermissions(AbstractDynamoDBQuery.java:81) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery$CollectionExecution.execute(AbstractDynamoDBQuery.java:100) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.execute(AbstractDynamoDBQuery.java:311) ~[spring-data-dynamodb-5.1.0.jar:5.1.0]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.3.jar:2.6.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.18.jar:5.3.18]
    at com.sun.proxy.$Proxy69.findByMembersContaining(Unknown Source) ~[na:na]
    at com.example.dynamodbtest.controller.GroupController.getTestGroups(GroupController.java:24) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.60.jar:9.0.60]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

AWS DynamoDB Object
Group Object Showing String Set

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无需解释 2025-01-26 15:50:11

切换到增强型客户端后,我能够使用“过滤表达式”执行“扫描”以返回我想要的结果。

private DynamoDbClient getClient() {
    Region region = Region.US_EAST_2;
    return DynamoDbClient.builder()
            .region(region)
            .build();
}

private DynamoDbEnhancedClient getEnhancedClient() {
    return DynamoDbEnhancedClient.builder()
            .dynamoDbClient(getClient())
            .build();
}

public List<Group> scanGroupsByMember(String memberId) {

    DynamoDbTable<Group> groupTable = getEnhancedClient().table("GroupTable", TableSchema.fromClass(Group.class));

    AttributeValue attributeValue = AttributeValue.builder()
            .s(memberId)
            .build();

    Map<String, AttributeValue> expressionValues = new HashMap<>();
    expressionValues.put(":value", attributeValue);

    Expression expression = Expression.builder()
            .expression("contains(members, :value)")
            .expressionValues(expressionValues)
            .build();

    ScanEnhancedRequest scanEnhancedRequest = ScanEnhancedRequest.builder()
            .filterExpression(expression)
            .build();

    return groupTable.scan(scanEnhancedRequest).items().stream().collect(Collectors.toList());

}

Swapping to Enhanced Client, I was able to perform a 'Scan' with a 'Filter Expression' to return the results I want.

private DynamoDbClient getClient() {
    Region region = Region.US_EAST_2;
    return DynamoDbClient.builder()
            .region(region)
            .build();
}

private DynamoDbEnhancedClient getEnhancedClient() {
    return DynamoDbEnhancedClient.builder()
            .dynamoDbClient(getClient())
            .build();
}

public List<Group> scanGroupsByMember(String memberId) {

    DynamoDbTable<Group> groupTable = getEnhancedClient().table("GroupTable", TableSchema.fromClass(Group.class));

    AttributeValue attributeValue = AttributeValue.builder()
            .s(memberId)
            .build();

    Map<String, AttributeValue> expressionValues = new HashMap<>();
    expressionValues.put(":value", attributeValue);

    Expression expression = Expression.builder()
            .expression("contains(members, :value)")
            .expressionValues(expressionValues)
            .build();

    ScanEnhancedRequest scanEnhancedRequest = ScanEnhancedRequest.builder()
            .filterExpression(expression)
            .build();

    return groupTable.scan(scanEnhancedRequest).items().stream().collect(Collectors.toList());

}
木緿 2025-01-26 15:50:11

“我正在使用AWS Java SDK DynamoDB版本1.12.192”。

您应该使用 aws sdk进行Java V2 ,并使用增强的客户端将Java类映射到DynamoDB表。这是最好的做法,而不是使用旧的V1 API。请参阅此文档主题:

假设我们有一个名为 id 的键的工作表。下图显示了表。

要映射到此表,您可以创建一个使用 @dynamodbbean 这样的类:

 import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
        
            @DynamoDbBean
             public class Work {
        
               private String id;
               private String date;
               private String description ;
               private String guide;
               private String username ;
               private String status  ;
               private String archive   ;
        
               @DynamoDbPartitionKey
               public String getId() {
                 return this.id;
               }
        
               public void setId(String id) {
                this.id = id;
               }
        
               @DynamoDbSortKey
               public String getName() {
                return this.username;
                }
        
               public void setArchive(String archive) {
                this.archive = archive;
                }
        
               public String getArchive() {
                 return this.archive;
                }
        
               public void setStatus(String status) {
                 this.status = status;
               }
        
               public String getStatus() {
                return this.status;
               }
        
              public void setUsername(String username) {
               this.username = username;
              }
        
              public String getUsername() {
               return this.username;
              }
        
              public void setGuide(String guide) {
                this.guide = guide;
            }
        
              public String getGuide() {
                return this.guide;
              }
        
              public String getDate() {
               return this.date;
               }
        
              public void setDate(String date) {
               this.date = date;
              }
        
              public String getDescription() {
               return description;
              }
        
             public void setDescription(String description) {
              this.description = description;
               }
              }

使用增强的客户端执行CRUD操作,创建 DynamoDbtable 对象。

// Create a DynamoDbEnhancedClient.
 DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(getClient())
                .build();

 // Create a DynamoDbTable object.
 DynamoDbTable<Work> workTable = enhancedClient.table("Work", TableSchema.fromBean(Work.class));

现在您可以执行CRUD操作。要将记录放入表中,您可以创建工作对象并设置数据。然后调用 dynamodbtable 对象 putitem 方法。

// Populate the table.
 Work record = new Work();
 record.setUsername(item.getName());
 record.setId(myGuid);
 record.setDescription(item.getDescription());
 record.setDate(now()) ;
 record.setStatus(item.getStatus());
 record.setArchive("Open");
 record.setGuide(item.getGuide());

 // Put the customer data into a DynamoDB table.
  workTable.putItem(record);

A Mazon DynamoDB API V2 (包括增强的客户端)也可以在Spring Boot应用中使用。要了解如何构建样品Spring Boot Web应用程序,请参阅此 aws教程

"I am using AWS Java SDK DynamoDB version 1.12.192".

You should use AWS SDK for Java V2 and to map Java classes to a DynamoDB table by using the Enhanced Client. This is best practice as opposed to using the old V1 API. See this doc topic:

Using the DynamoDB Enhanced Client in the AWS SDK for Java 2.x

Assume we have a Work table with a key named id. The following illustration shows the table.

enter image description here

TO map to this table, you can create a class that uses the @DynamoDbBean annotation like this:

 import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
        
            @DynamoDbBean
             public class Work {
        
               private String id;
               private String date;
               private String description ;
               private String guide;
               private String username ;
               private String status  ;
               private String archive   ;
        
               @DynamoDbPartitionKey
               public String getId() {
                 return this.id;
               }
        
               public void setId(String id) {
                this.id = id;
               }
        
               @DynamoDbSortKey
               public String getName() {
                return this.username;
                }
        
               public void setArchive(String archive) {
                this.archive = archive;
                }
        
               public String getArchive() {
                 return this.archive;
                }
        
               public void setStatus(String status) {
                 this.status = status;
               }
        
               public String getStatus() {
                return this.status;
               }
        
              public void setUsername(String username) {
               this.username = username;
              }
        
              public String getUsername() {
               return this.username;
              }
        
              public void setGuide(String guide) {
                this.guide = guide;
            }
        
              public String getGuide() {
                return this.guide;
              }
        
              public String getDate() {
               return this.date;
               }
        
              public void setDate(String date) {
               this.date = date;
              }
        
              public String getDescription() {
               return description;
              }
        
             public void setDescription(String description) {
              this.description = description;
               }
              }

To use the Enhanced Client to perform CRUD operation, create a DynamoDbTable object.

// Create a DynamoDbEnhancedClient.
 DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(getClient())
                .build();

 // Create a DynamoDbTable object.
 DynamoDbTable<Work> workTable = enhancedClient.table("Work", TableSchema.fromBean(Work.class));

Now you can perform CRUD operations. To place a record into the table, you can create a Work object and set the data. Then call the DynamoDbTable objects putItem method.

// Populate the table.
 Work record = new Work();
 record.setUsername(item.getName());
 record.setId(myGuid);
 record.setDescription(item.getDescription());
 record.setDate(now()) ;
 record.setStatus(item.getStatus());
 record.setArchive("Open");
 record.setGuide(item.getGuide());

 // Put the customer data into a DynamoDB table.
  workTable.putItem(record);

The Amazon DynamoDB API V2 (Including the Enhanced Client) can be used within a Spring BOOT app too. To learn How TO build a SAMPLE Spring Boot web App, see this AWS tutorial.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文