2

I have created a java service to get the details from dynamodb it is working fine but my challenge is i hardcoded the table name to the class file @DynamoDbTable annotation in order to work with different environments i feel it is not the right way. I have given my code below could someone help me to resolve the issue.

Code sample

public class DynamodbService {

    private DynamoDB client;
    private DynamoDBMapper objectMapper;

    /**
     * 
     * @param client
     * @param objectMapper
     */
    @Autowired
    public DynamodbService(DynamoDB client, DynamoDBMapper objectMapper) {
        this.client = client;
        this.objectMapper = objectMapper;
    }


    public List<Dynamodb> findAll() throws Exception {
        DynamoDBMapperConfig mapperConfig = new DynamoDBMapperConfig.Builder()
                .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement(""))
                .build();
        DynamoDBMapper mapper = new DynamoDBMapper(client, mapperConfig);

        DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();

        List<Dynamodb> scanResult = objectMapper.scan(Dynamodb.class, scanExpression);
        return scanResult;
    }

}

My DynamoDB config

@Configuration
public class DynamoDBconfig {
    /**
     * 
     */
    @Value("${amazon.dynamodb.accesskey}")
    private String awsAccessKey;
    /**
     * 
     */
    @Value("${amazon.dynamodb.secretkey}")
    private String awsSecretKey;

    
    @Bean
    public AWSCredentials amazonAWSCredentials() {
        return new BasicAWSCredentials(aes.getDecryptedvalue(awsAccessKey), aes.getDecryptedvalue(awsSecretKey));
    }

    /**
     * 
     * @return
     */
    @Bean
    public DynamoDBMapperConfig dynamoDBMapperConfig() {
        return DynamoDBMapperConfig.DEFAULT;
    }

    /**
     * 
     * @param amazonDynamoDB
     * @param config
     * @return
     */
    @Bean
    public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig config) {
        return new DynamoDBMapper(amazonDynamoDB, config);
    }

    /**
     * 
     * @return
     */
    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        return AmazonDynamoDBClientBuilder.standard().withCredentials(amazonAWSCredentialsProvider())
                .withRegion(Regions.US_EAST_2).build();
    }

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

    /**
     * 
     * @return
     */
    public AWSCredentialsProvider amazonAWSCredentialsProvider() {
        return new AWSStaticCredentialsProvider(amazonAWSCredentials());
    }

}

ERROR in my dynamodb service

The constructor DynamoDBMapper(DynamoDB, DynamoDBMapperConfig) is undefined

I am unable find out what is the issue. If i use table name in class file it's working fine if i try to replace the table name using code it ends up with error.

1 Answer 1

5

DynamoDBMapper expects any implementation of AmazonDynamoDB but not DynamoDB class.

public DynamoDBMapper(
            final AmazonDynamoDB dynamoDB,
            final DynamoDBMapperConfig config) {

You need to inject only the DynamoDBMapper in your service.

@Bean
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB) {
  DynamoDBMapperConfig config = new DynamoDBMapperConfig.Builder().withTableNameOverride(TableNameOverride.withTableNameReplacement(tableName))
        .build();
   return new DynamoDBMapper(amazonDynamoDB, config);
}

Other option could be using com.amazonaws.services.dynamodbv2.document.DynamoDB class but there you could not use DynamoDBScanExpression and you need to rewrite your code.


String desiredTabledName = "table-name";
Table table = dynamoDB.getTable(desiredTabledName);


You have multiple options.

 - table.scan() and table query.
 - Index index = table.getIndex(indexName);
   index.scan() or index.query()
 - You could pass `QuerySpec` and `ScanSpec` to all above.  
Sign up to request clarification or add additional context in comments.

1 Comment

In my case it requires to specify mapper with overriding in my @EnableDynamoDBRepositories. So it should be like @EnableDynamoDBRepositories(basePackages = "<your repo package>", amazonDynamoDBRef = "<name of your AmazonDynamoDB bean>", dynamoDBMapperRef = "dynamoDBMapper"). Otherwise the repo will look to another (default) mapper without overriding policy. Hope it'll help somebody

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.