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.

@DynamoDbImmutable is ignored. Error: "DynamoDb bean class must be annotated with @DynamoDbBean"

See original GitHub issue

Can’t get example from the docs with @DynamoDbImmutable working.

Describe the bug

Attempts to create a DynamoDbTable object fail with “A DynamoDb bean class must be annotated with @DynamoDbBean” error.

Expected Behavior

Should be no error.

Current Behavior

Error stack trace is below.

Caused by: java.lang.IllegalArgumentException: A DynamoDb bean class must be annotated with @DynamoDbBean
	at software.amazon.awssdk.enhanced.dynamodb.mapper.BeanTableSchema.createStaticTableSchema(BeanTableSchema.java:156) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at software.amazon.awssdk.enhanced.dynamodb.mapper.BeanTableSchema.create(BeanTableSchema.java:124) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at software.amazon.awssdk.enhanced.dynamodb.mapper.BeanTableSchema.create(BeanTableSchema.java:116) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at software.amazon.awssdk.enhanced.dynamodb.TableSchema.fromBean(TableSchema.java:80) ~[dynamodb-enhanced-2.15.49.jar!/:?]
	at no.example.customer_store.CustomerStoreDAO.<init>(CustomerStoreDAO.java:23) ~[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 following code works fine.

@DynamoDbBean
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
    String primaryKey;
    String sortKey;
    Instant created;

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

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

This code fails.

@Value
@Builder
@DynamoDbImmutable(builder = Customer.CustomerBuilder.class)
public class Customer {
    String primaryKey;
    String sortKey;
    Instant created;

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

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

Code from the example without Lombok also fails.

@DynamoDbImmutable(builder = Customer.Builder.class)
public class Customer {
    private final String primaryKey;
    private final String sortKey;
    private final Instant created;

    private Customer(Builder b) {
        this.primaryKey = b.primaryKey;
        this.sortKey = b.sortKey;
        this.created = b.created;
    }

    public static Builder builder() {
        return new Builder();
    }

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

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

    public static final class Builder {
        private String primaryKey;
        private String sortKey;
        private Instant created;

        public Builder primaryKey(String primaryKey) {
            this.primaryKey = primaryKey;
            return this;
        }

        public Builder sortKey(String sortKey) {
            this.sortKey = sortKey;
            return this;
        }

        public Builder created(Instant created) {
            this.created = created;
            return this;
        }

        public Customer build() {
            return new Customer(this);
        }
    }
}

DynamoDbTable object is created like this.

public class CustomerStoreDAO {
    private DynamoDbTable<Customer> customerStoreTable;

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

Possible Solution

Context

Your Environment

  • AWS Java SDK version used: 2.15.49
  • JDK version used: AdoptOpenJDK (build 1.8.0_242-b08
  • Operating System and version: macOS Catalina 10.15.7

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
mahtabsabetcommented, Dec 22, 2020

I was having this same issue - the problem was I was calling .fromBean(). When I changed it to .fromImmutableClass(), it started working.

1reaction
debora-itocommented, Jan 4, 2021

@bigunyak that’s the documentation link I was hoping to get, I’ll add this info to make it more clear.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to apply DynamoDB Bean annotations to a different ...
Due to @DynamoDbBean using the entity class name as a DynamoDB table name, I put custom annotation to assign custom table name there:...
Read more >
Introducing immutable class mapping for the Enhanced ... - AWS
First, create and annotate an immutable class that will map to records in your DynamoDB table. You may either follow the example below...
Read more >
software.amazon.awssdk.enhanced.dynamodb.mapper ...
This annotation is used to flatten all the attributes of a separate DynamoDb bean that is stored in the current bean object and...
Read more >
TableSchema (AWS Java SDK :: DynamoDB - javadoc.io
Scans a bean class that has been annotated with DynamoDb bean annotations and ... DynamoDbImmutable This is a moderately expensive operation, and should...
Read more >
AWS Java SDK V2. DynamoDB enhanced with Kotlin
The @DynamoDbBean annotation needs to be applied to the Java POJO class, which has a default public constructor and standard-named getters ...
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