Skip to content

DynamoDB Enhanced Client support for non-public classes #1804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
swaranga opened this issue Apr 30, 2020 · 5 comments
Closed

DynamoDB Enhanced Client support for non-public classes #1804

swaranga opened this issue Apr 30, 2020 · 5 comments
Labels
dynamodb-enhanced feature-request A feature should be added or improved. wontfix We have determined that we will not resolve the issue.

Comments

@swaranga
Copy link

This issue represents the desire for the DynamoDB Enhanced Client to be able to support Java classes that are not declared public.

Why is this desirable?

  • Typically, in a large application, I want to separate my DB model from the domain/business model. In this context my classes that represent records in DynamoDB are the data model which I want to hide from clients.
  • For such cases, I would like to declare them as non-public classes - may be package private. Unfortunately the DDB mapper does not allows such classes to be used.
@swaranga swaranga added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Apr 30, 2020
@bmaizels
Copy link
Contributor

bmaizels commented May 1, 2020

@swaranga are you using StaticTableSchema or BeanTableSchema?

@swaranga
Copy link
Author

swaranga commented May 1, 2020

I am using the BeanTableSchema

@bmaizels
Copy link
Contributor

bmaizels commented May 1, 2020

This can't be done with the BeanTableSchema because of limitations of Java. The introspection is done by a class outside of the privilege scope of your protected class. However, there is a solution if you're willing to use the StaticTableSchema, because you can resolve the lambda functions to perform gets/sets and instantiations from within your own package, or even within the class itself (allowing you to access private methods). Here's an example that I just tested with and works great:

class SimpleBean {
    static final TableSchema<SimpleBean> TABLE_SCHEMA =
        TableSchema.builder(SimpleBean.class)
                   .newItemSupplier(SimpleBean::new)
                   .addAttribute(String.class, a -> a.name("id")
                                                     .getter(SimpleBean::getId)
                                                     .setter(SimpleBean::setId)
                                                     .tags(primaryPartitionKey()))
                   .build();

    private String id;

    SimpleBean() {

    }

    String getId() {
        return id;
    }

    void setId(String id) {
        this.id = id;
    }
}

Note that because the schema is declared from within the class itself it has no access problems. This would also work from within the same package for this particular example.

@bmaizels bmaizels closed this as completed May 1, 2020
@bmaizels bmaizels added wontfix We have determined that we will not resolve the issue. and removed needs-triage This issue or PR still needs to be triaged. labels May 1, 2020
@swaranga
Copy link
Author

swaranga commented May 2, 2020

Jackson can serialize and deserialize package private classes with no problems. Could we take a look at how they do it?

While the StaticSchema works, it is still very verbose; no doubt it is less than having to write all the getItem/PutItem requests by hand but still verbose than the BeanTableSchema. And everytime you add a field, you need to remember to add it to the schema. Hopefully forgetting this would be caught by a unit test but it is still annoying. Thoughts?

@bmaizels
Copy link
Contributor

bmaizels commented May 2, 2020

Jackson can serialize and deserialize package private classes with no problems. Could we take a look at how they do it?

We're using the Introspector that Java provides that follows pretty strict patterns when it comes to discovering properties of Java Beans (documented in section 8.3.1 of the Java Bean standard). There's no way to configure the java Introspector to relax these rules, so the alternative is building one from the ground up and do it your own way, but we chose to follow the spec in this case (which is why we named it the -Bean- TableSchema).

While the StaticSchema works, it is still very verbose; no doubt it is less than having to write all the getItem/PutItem requests by hand but still verbose than the BeanTableSchema. And everytime you add a field, you need to remember to add it to the schema. Hopefully forgetting this would be caught by a unit test but it is still annoying. Thoughts?

I think it's personal preference. I'm personally not a big fan of beans and I want my cold-start time to be minimal, so I tend to prefer working with the StaticTableSchema (and I've spoken to other developers that feel the same), but there are also many that prefer it just to work and are used to working with beans so we try and provide for both.

If and when we build an annotation implementation for ImmutableTableSchema (still very much in the works), this would be using custom written introspection and would not be constrained by the bean standard so we'll have more options there and maybe the right time to revisit this issue.

The other possibility for the future is writing an annotation processor to generate a TableSchema, it may be possible to get the best of both worlds that way, the convenience of not having to add fields manually to the TableSchema, but also the power and flexibility of having a static tableschema rather than an introspected one.

aws-sdk-java-automation added a commit that referenced this issue Nov 1, 2021
…5b7f3b3b9

Pull request: release <- staging/08a20c76-b7d2-46fe-abac-6af5b7f3b3b9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dynamodb-enhanced feature-request A feature should be added or improved. wontfix We have determined that we will not resolve the issue.
Projects
None yet
Development

No branches or pull requests

3 participants