boostchicken库下DynamoDB表名覆盖配置对GSI查询失效问题
问题根因
你遇到的问题是 DynamoDBMapperConfig 中使用 withTableNameReplacement 配置的表名覆盖规则仅对主表主键查询生效,GSI查询场景下,底层请求构建逻辑会优先读取 @DynamoDBTable 注解的原始表名拼接索引,不会触发全局表名替换,因此会访问不存在的原始表名导致报错。
解决方案
方案一:使用自定义TableNameResolver(兼容性最好,推荐)
改用自定义表名解析器实现全场景的表名动态替换,不管是主表查询还是GSI查询都会走该解析逻辑,修改你的DynamoDBMapperConfig Bean配置即可:
@Bean @Primary public DynamoDBMapperConfig dynamoDBMapperConfig() { // 自定义表名解析器,统一处理所有表的环境后缀拼接 DynamoDBMapperConfig.TableNameResolver tableNameResolver = (clazz, config) -> { DynamoDBTable tableAnno = clazz.getAnnotation(DynamoDBTable.class); if (tableAnno == null) { throw new IllegalArgumentException("实体类未添加@DynamoDBTable注解"); } String originalTableName = tableAnno.tableName(); if ("accounts".equals(originalTableName)) { return "accounts-" + env.getEnvironment(); } // 其他表的动态表名规则也可以在这里扩展 return originalTableName; }; return DynamoDBMapperConfig.builder() .withTableNameResolver(tableNameResolver) .withBatchLoadRetryStrategy(DynamoDBMapperConfig.DEFAULT.getBatchLoadRetryStrategy()) .withBatchWriteRetryStrategy(DynamoDBMapperConfig.DEFAULT.getBatchWriteRetryStrategy()) .withConsistentReads(DynamoDBMapperConfig.DEFAULT.getConsistentReads()) .withConversionSchema(DynamoDBMapperConfig.DEFAULT.getConversionSchema()) .withPaginationLoadingStrategy(DynamoDBMapperConfig.DEFAULT.getPaginationLoadingStrategy()) .withRequestMetricCollector(DynamoDBMapperConfig.DEFAULT.getRequestMetricCollector()) .withSaveBehavior(DynamoDBMapperConfig.DEFAULT.getSaveBehavior()) .withTypeConverterFactory(DynamoDBMapperConfig.DEFAULT.getTypeConverterFactory()) .build(); }
注意:删除原来配置中重复的
withObjectTableNameResolver配置,同时移除原来的withTableNameOverride配置。
方案二:注解使用占位符(适合版本较新的场景)
如果你使用的spring-data-dynamodb版本支持注解属性的Spring占位符解析,可以直接修改实体类的@DynamoDBTable注解:
@DynamoDBTable(tableName = "accounts-${env.name:staging}")
其中${env.name}对应你配置文件中的环境变量key,不需要额外修改DynamoDB配置类,该方案更简洁但兼容性弱于方案一。
内容的提问来源于stack exchange,提问作者abdelgany mahmoud
相关产品推荐
相关产品推荐

