question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TableNameOverride Prefix not applying

See original GitHub issue

Expected Behavior I am using the following relevant classes, built from multiple examples for running a local testing version of DynamoDB to get more familiar with the framework:

General configuration

    @Configuration
    @EnableDynamoDBRepositories(
        dynamoDBMapperConfigRef = "dynamoDBMapperConfig",
        basePackages = "my.model.package") 
    public class DynamoDBConfig {

    private static final Logger log = LoggerFactory.getLogger(DynamoDBConfig.class);

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

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

    @Value("${amazon.dynamodb.tableNameOverride}")
    private String tablePrefix;

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

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


    @Bean
    public DynamoDBMapperConfig dynamoDBMapperConfig() {
        // Create empty DynamoDBMapperConfig builder
        DynamoDBMapperConfig.Builder builder = DynamoDBMapperConfig.builder();
        builder.setTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(tablePrefix));

        return new DynamoDBMapperConfig(DynamoDBMapperConfig.DEFAULT, builder.build());
    }

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

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        return AmazonDynamoDBClientBuilder.standard()
                .withCredentials(amazonAWSCredentialsProvider())
                .withEndpointConfiguration(
                        new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "eu-central-1")
                )
                .build();
    }

    @Bean
    public DynamoDBMappingContext dynamoDBMappingContext() {
        return new DynamoDBMappingContext();
    }
`

Class that is run after successful application start to setup database “schema”

    @Service
    public class DBSetupRunner {

    final Logger log = LoggerFactory.getLogger(DBSetupRunner.class);

    @Value("${amazon.dynamodb.tableNameOverride}")
    private String tablePrefix;

    @EventListener(ApplicationReadyEvent.class)
    public void main() throws Exception {
        AmazonDynamoDB dynamodb = null;
        System.setProperty("sqlite4java.library.path", "native-libs");

        // Create an in-memory and in-process instance of DynamoDB Local that runs over HTTP
        final String[] localArgs = { "-inMemory" };
        DynamoDBProxyServer server = null;
            server = ServerRunner.createServerFromCommandLineArgs(localArgs);
            server.start();

            dynamodb = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(

                    new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "eu-central-1"))
                    .build();

        setupDBSchema(dynamodb);
    }


    public void setupDBSchema(AmazonDynamoDB dynamodb){

        CreateTableResult res = createTable(dynamodb, tablePrefix + "Example", "Id");
        listTables(dynamodb.listTables(), "DynamoDB Local over HTTP");
    }

    private static void listTables(ListTablesResult result, String method) {
        System.out.println("found " + Integer.toString(result.getTableNames().size()) + " tables with " + method);
        for(String table : result.getTableNames()) {
            System.out.println(table);
        }
    }

    private static CreateTableResult createTable(AmazonDynamoDB ddb, String tableName, String hashKeyName) {
        List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
        attributeDefinitions.add(new AttributeDefinition(hashKeyName, ScalarAttributeType.S));

        List<KeySchemaElement> ks = new ArrayList<KeySchemaElement>();
        ks.add(new KeySchemaElement(hashKeyName, KeyType.HASH));

        ProvisionedThroughput provisionedthroughput = new ProvisionedThroughput(1000L, 1000L);

        CreateTableRequest request =
                new CreateTableRequest()
                        .withTableName(tableName)
                        .withAttributeDefinitions(attributeDefinitions)
                        .withKeySchema(ks)
                        .withProvisionedThroughput(provisionedthroughput);

        return ddb.createTable(request);
    }
    }

I then access the tables using basic SpringData-based RestController and Repository classes after setting amazon.dynamodb.tableNameOverride=dev_ . in my properties file. I expected the mapping to access “dev_Example” due to the override instead of “Example”, which is stated in the model class via @DynamoDBTable(tableName = "Example") .

Actual Behavior When I now try to GET any information from the Example table, I get this error:

com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException: Cannot do operations on a non-existent table (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: b600800b-0e21-4793-8220-78febf0aead0)

because the application still tries to access “Example” instead of “dev_Example” which was created in the runner.

Steps to Reproduce the Problem

  1. Start up application with mentioned configuration
  2. call any REST endpoint accessing data from the “Example”-table.

Specifications

  • Spring Data DynamoDB Version:
<dependency>
			<groupId>com.github.derjust</groupId>
			<artifactId>spring-data-dynamodb</artifactId>
			<version>5.0.2</version>
		</dependency>
		<dependency>
			<groupId>com.amazonaws</groupId>
			<artifactId>DynamoDBLocal</artifactId>
			<version>[1.11,2.0)</version>
		</dependency>
  • Spring Data Version: 2.0.3.RELEASE
  • AWS SDK Version:
<dependency>
			<groupId>com.amazonaws</groupId>
			<artifactId>aws-java-sdk-dynamodb</artifactId>
			<version>1.11.351</version>
		</dependency>
  • Java Version: 10.0.1 - Java HotSpot™ 64-Bit Server VM 10.0.1+10
  • Platform Details: Running from IntelliJ IDEA Spring plugin for Maven.

I tried multiple different versions, some including the stuff that is referenced in the wiki, but the prefix is never applied to my queries once my application start up.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:5
  • Comments:8

github_iconTop GitHub Comments

3reactions
eggsy84commented, Aug 30, 2018

Might help some people but after reviewing #59

I’ve found that it still works (in 5.03) using XML config.

Created a demo repo that might help people here:

https://github.com/clos-consultancy/SpringDynamoDB

2reactions
GonzaloSaadcommented, Oct 4, 2018

Hello.

I’ve been checking this today, with the same approach that you have. The only thing I changed is the name of the property on application.properties file and the way to instantiate the DynamoDBMapperConfig object.

I’ve used amazon.dynamodb.tableNamePrefix instead of amazon.dynamodb.tableNameOverride. It seems that this last one redefines the table name. I’m not sure anyways on that.

I made up the name of the property amazon.dynamodb.tableNamePrefix. Don’t know if exists haha.

On the configuration class, I have.

@Configuration
@EnableDynamoDBRepositories(
        dynamoDBMapperConfigRef = "dynamoDBMapperConfig",
        basePackages = "package.of.repo")
public class DynamoDBConfig {

    private static final String SEPARATOR = "-";

    @Value("${amazon.dynamodb.tableNamePrefix}")
    private String tablePrefix;

    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        return AmazonDynamoDBClientBuilder
                .standard()
                .withRegion(Regions.fromName(Environment.getRegion()))
                .build();
    }

    @Bean
    public DynamoDBMapperConfig dynamoDBMapperConfig() {
        DynamoDBMapperConfig.Builder builder = DynamoDBMapperConfig.builder();
        builder.setTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(getFormattedPrefix()));
        return builder.build();
    }

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

    private String getFormattedPrefix(){
        return tablePrefix + SEPARATOR;
    }
}

Maybe this could help you too.

Read more comments on GitHub >

github_iconTop Results From Across the Web

DynamoDB and TableNameOverride with prefix - Stack Overflow
I first thought of putting them in separate regions but not sure about this. Could also use this: mapper.save(ck, new DynamoDBMapperConfig(new ...
Read more >
DynamoDBMapperConfig (AWS SDK for Java - 1.12.365)
tableNameOverride - An override for the table name, or null for no override. paginationLoadingStrategy - The pagination loading strategy, or null for default....
Read more >
Java – DynamoDB and TableNameOverride with prefix – iTecNote
I am testing DynamoDB tables and want to set up different table names for prod and dev environment using the prefix "dev_" for...
Read more >
GT's Blog
But it's not like working in the assembly line. ... to configure the DynamoDBMapper and provide a custom/dynamic table name prefix using TableNameOverride....
Read more >
com.amazonaws.services.dynamodbv2 ... - Download JAR files
public static enum SaveBehavior { /** * UPDATE will not affect unmodeled attributes on a ... public static TableNameOverride withTableNamePrefix( String ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found