Skip to content

Can't create DynamoDbIndex object with DynamoDbEnhancedClient #2213

Closed
@bigunyak

Description

@bigunyak

Describe the bug

The DynamoDbIndex<T> index(String indexName) method fails with "Attempt to execute an operation that requires a secondary index without defining the index attributes in the table metadata." error.

Expected Behavior

Index object should be created successfully.

Current Behavior

Trace log is below.

Caused by: java.lang.IllegalArgumentException: Attempt to execute an operation that requires a secondary index without defining the index attributes in the table metadata. Index name: gsiAuthorizationTable
	at software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableMetadata.getIndex(StaticTableMetadata.java:145) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableMetadata.indexPartitionKey(StaticTableMetadata.java:78) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at software.amazon.awssdk.enhanced.dynamodb.internal.client.DefaultDynamoDbTable.index(DefaultDynamoDbTable.java:85) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at software.amazon.awssdk.enhanced.dynamodb.internal.client.DefaultDynamoDbTable.index(DefaultDynamoDbTable.java:47) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at no.example.customer_store.CustomerStoreDAO.<init>(CustomerStoreDAO.java:28) ~[classes!/:1]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_242]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_242]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_242]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_242]
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:203) ~[spring-beans-5.2.4.RELEASE.jar!/:5.2.4.RELEASE]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans-5.2.4.RELEASE.jar!/:5.2.4.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:310) ~[spring-beans-5.2.4.RELEASE.jar!/:5.2.4.RELEASE]
	... 27 more

Steps to Reproduce

The code is loading as part of Spring Boot application and connects to running locally DynamoDB. The application starts with the following relevant classes.

@Configuration
public class CustomerContext {

    @Bean
    @Primary
    public DynamoDbEnhancedClient enhancedDynamoDBClient() {
        return DynamoDbEnhancedClient.builder()
                .dynamoDbClient(dynamoDBClient())
                .build();
    }

    @Bean
    @Primary
    @SneakyThrows
    public DynamoDbClient dynamoDBClient() {
        return DynamoDbClient.builder()
                .endpointOverride(new URI("http://localhost:8000"))
                .region(Region.of("eu-west-1"))
                .build();
    }
}
@Getter
@Setter
@DynamoDbBean
public class Customer {
    private String primaryKey;
    private String sortKey;
    private String gsiPrimaryKey;
    private String gsiSortKey;
    private Instant created;

    @DynamoDbPartitionKey
    public String getPrimaryKey() {
        return this.primaryKey;
    }

    @DynamoDbSortKey
    public String getSortKey() {
        return this.sortKey;
    }

    @DynamoDbSecondaryPartitionKey(indexNames = "gsiAuthorizationTable")
    public String getGSIPrimaryKey() {
        return this.gsiPrimaryKey;
    }

    @DynamoDbSecondarySortKey(indexNames = "gsiAuthorizationTable")
    public String getGSISortKey() {
        return this.gsiSortKey;
    }
}
@Slf4j
@Getter
@Service
public class CustomerStoreDAO {
    private static final String TABLE_NAME = "customer_store";
    public static final String GSI = "gsiAuthorizationTable";

    private DynamoDbTable<Customer> customerStoreTable;

    private DynamoDbIndex<Customer> authorizationTable;

    public CustomerStoreDAO(CustomerContext customerContext, DynamoDbEnhancedClient dynamoDbEnhancedClient) {
        this.customerStoreTable = dynamoDbEnhancedClient.table(TABLE_NAME, TableSchema.fromBean(Customer.class));

        this.authorizationTable = customerStoreTable.index(GSI);
    }
}

Possible Solution

Context

The problem makes it impossible to work with GSI through DynamoDbEnhancedClient.

Your Environment

  • AWS Java SDK version used: 2.15.49
  • JDK version used:
    openjdk version "1.8.0_242"
    OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_242-b08)
    OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.242-b08, mixed mode)
  • Operating System and version: macOS Catalina 10.15.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions