Skip to content

Alter table name during runtime

Joe Tan edited this page Jun 26, 2020 · 7 revisions

By default, table names are statically defined via the entity class annotation:

package com.acme.repository;

@DynamoDBTable(tableName = "someEntityTableName")
public class SomeEntity {
    ...
}

The table names can be altered via an altered DynamoDBMapperConfig bean:

⚠️ Using the correct builder for DynamoDBMapperConfig is important! ⚠️

new DynamoDBMapperConfig.Builder() should be used to start with a DEFAULT configuration and only overriding fields that should differ - like TableNameOverride.

Older versions of this sample code started with DynamoDBMapperConfig.builder() which sets all fields to null potentially causing NullPointerExceptions later on!

@Configuration
@EnableDynamoDBRepositories(
    dynamoDBMapperConfigRef = "dynamoDBMapperConfig",  // This literal has to match the bean name - otherwise the default DynamoDBMapperConfig will be used
    basePackages = "com.acme.repository") // The package with the @DynamoDBTable entity classes
public class DynamoDBConfig {
    @Bean
    public DynamoDBMapperConfig dynamoDBMapperConfig(TableNameOverride tableNameOverrider) {
        // Create empty DynamoDBMapperConfig builder
	DynamoDBMapperConfig.Builder builder = new DynamoDBMapperConfig.Builder();
	// Inject missing defaults from the deprecated method
	builder.withTypeConverterFactory(DynamoDBTypeConverterFactory.standard());
	builder.withTableNameResolver(DefaultTableNameResolver.INSTANCE);
        // Inject the table name overrider bean
	builder.withTableNameOverride(tableNameOverrider());
	return builder.build();
    }
    
    @Bean
    public TableNameOverride tableNameOverrider() {
        ...
    }
}

TableNameOverride is a AWS SDK DynamoDB class and not exclusive to spring-data-dynamodb. There are static builder methods that expose some default behavior that is sufficient for most scenarios:

Prefix each table with a literal:

    @Bean
    public TableNameOverride tableNameOverrider() {
        String prefix = ... // Use @Value to inject values via Spring or use any logic to define the table prefix
        return TableNameOverride.withTableNamePrefix(prefix);
    }

or resolve each table name to the same one:

    @Bean
    public TableNameOverride tableNameOverrider() {
        String singleTableName = ... // Use @Value to inject values via Spring or use any logic to define the table prefix
        return TableNameOverride.withTableNameReplacement(singleTableName);
    }