Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
5.2k views
in Technique[技术] by (71.8m points)

java - Problem with setting tableName dynamically with Spring Boot and DynamoDB using older version of spring-data-dynamodb

I am working on some legacy project, which uses 1.5.15.RELEASE Spring Boot version. Due to this I am using spring-data-dynamodb version 4.5.7. My problem is kind of sibling to this. I tried the solutions provided in that topic - including setting TableNameOverride and also custom TableNameResolver. Unfortunately all the findBy methods handled automatically by spring-data-dynamodb:4.5.7 are quering static table name - let's call it Item. I also have some custom methods implemented in RepositoryImpl class, where I @Autowire bean of DynamoDBMapper. Suprisingly, queries implemented manually (not handled by spring-data-dynamodb:4.5.7) are querying table with correct prefix i.e. TEST_Item.

ItemsRepository (this methods do not apply prefix, when querying - does not work, still queries Item table):

public interface ItemRepository extends CrudRepository<Item, ItemId>, ItemCustomRepository {
    Iterable<Item> findAllByInstanceId(Long instanceId);
    Iterable<Item> findAllByInstanceIdOrderByInsertedDateDesc(Long instanceId);
}

ItemsRepositoryImpl (this method do apply prefix, when querying - works fine, queries TEST_Item):

public class ItemRepositoryImpl implements ItemCustomRepository {
    @Autowired
    private DynamoDBMapper dynamoDBMapper;
    @Override
    public List<Item> findByInstanceIdAndMessageLike(Long instanceId, String search, String stepCode) {
        DynamoDBQueryExpression<Item> queryExpression = new DynamoDBQueryExpression<Item>()
                //... here building some query - not important;

        PaginatedQueryList<Item> queryList = dynamoDBMapper.query(Item.class, queryExpression);

        return response;
    }

Configuration class:

@Configuration
@EnableDynamoDBRepositories(amazonDynamoDBRef = "amazonDynamoDB", dynamoDBMapperConfigRef = "dynamoDBMapperConfig", basePackages = "com.shem.datasource.nosql.repository")
public class DynamoDBConfig {

    @Value("${amazon.dynamodb.region}")
    private String amazonDynamoDBRegion;
    @Value("${dynamo.proxy.host:}")
    private String proxyHost;
    @Value("${dynamo.proxy.port:80}")
    private Integer proxyPort;
    @Value("${dynamo.proxy.enabled:false}")
    private Boolean proxyEnabled;
    @Value("${amazon.dynamodb.tableNamePrefix:}")
    private String tableNamePrefix;

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        ClientConfiguration clientConfig = new ClientConfiguration();

        if (proxyEnabled) {
            clientConfig.setProxyHost(proxyHost);
            clientConfig.setProxyPort(proxyPort);
            clientConfig.setProxyProtocol(Protocol.HTTP);
        }

        AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard()
                .withClientConfiguration(clientConfig)
                .withRegion(amazonDynamoDBRegion)
                .build();

        return amazonDynamoDB;
    }

    @Bean
    public DynamoDB dynamoDB(AmazonDynamoDB amazonDynamoDB) {
        return new DynamoDB(amazonDynamoDB);
    }

    @Bean
    public DynamoDBMapperConfig dynamoDBMapperConfig() {
        DynamoDBMapperConfig.Builder builder = new DynamoDBMapperConfig.Builder();
        String finalPrefix = StringUtils.isNotBlank(tableNamePrefix) ? tableNamePrefix + "_" : "";
        
        builder.setPaginationLoadingStrategy(PaginationLoadingStrategy.ITERATION_ONLY);
        builder.setTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(finalPrefix));
        System.out.println("Prefix set to " + finalPrefix);
        return builder.build();
    }

    @Bean
    public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig dynamoDBMapperConfig) {
        return new DynamoDBMapper(amazonDynamoDB, dynamoDBMapperConfig);
    }
}

Seems like the problem is somewhere in spring-data-dynamodb:4.5.7, but maybe someone already faced such issue and can help. Any thoughts how to overcome this issue? The only solutions coming to my mind are from category not the best ideas:

  • remove spring-data-dynamodb at all and implement everything with just AWS Java SDK
  • try to change SpringBoot version to >2 and then try using newer version of spring-data-dynamodb, but project glows red when trying - timeconsuming..

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I recommend using the Amazon DynamoDB Java API V2. You can develop Spring Boot apps that are able to use the latest features of this API, such as the enhanced client, which maps fields in a class to items in a table.

Here is a developer article that walks you through step by step how to develop a Spring Boot app that uses DynamoDB Java API V2.

Creating the DynamoDB web application item tracker


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...