Customizing immutable data class methods
- Dominant language
- Java
- Stars
- 2.6k
- Forks
- 1k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 51
Description
Currently, methods belonging to a class that is annotated with @DynamoDbImmutable are constrained as follows:
1. Getters must be the attribute value that is stored in the table
2. The static Builder factory method must be called `builder()`
3. Builder setters must match the class getters
This restricts the user to how these methods can be named. For example, class getters cannot be prepended with the conventional `get`, builder setters cannot be prepended with `set` or `with`, and the static Builder factory method cannot be prepended with `new`.
These restrictions can be seen in the [README](https://github.com/aws/aws-sdk-java-v2/tree/master/services-custom/dynamodb-enhanced#working-with-immutable-data-classes).
## Describe the Feature
Allow users to customize class getters, builder setters, and the Builder factory method, similar to how [Immutables allows users to customize the style of generated code](https://immutables.github.io/style.html).
## Is your Feature Request related to a problem?
The problem is only stylistic and does not affect the actual functionality.
## Proposed Solution
The following is a partial implementation of the class included in the README that follows the current constraints.
```
@DynamoDbImmutable(builder = Customer.Builder.class)
public class Customer {
private final String accountId;
private final String name;
private Customer(Builder b) {
this.accountId = b.accountId;
this.name = b.name;
}
public static Builder builder() { return new Builder(); }
@DynamoDbPartitionKey
public String accountId() { return this.accountId; }
@DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name")
public String name() { return this.name; }
public static final class Builder {
private String accountId;
private String name;
private Builder() {}
public Builder accountId(String accountId) { this.accountId = accountId; return this; }
public Builder name(String name) { this.name = name; return this; }
public Customer build() { return new Customer(this); }
```
Now, the same class but with a flexible @DynamoDbImmutable annotation that can recognize getters, setters, and the Builder factory method.
```
@DynamoDbImmutable(
get = {"is*", "get*"},
init = "set*",
builderFactory = "newBuilder",
builder = Customer.Builder.class)
public class Customer {
private final String accountId;
private final String name;
private Customer(Builder b) {
this.accountId = b.accountId;
this.name = b.name;
}
public static Builder newBuilder() { return new Builder(); }
@DynamoDbPartitionKey
public String getAccountId() { return this.accountId; }
@DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name")
public String getName() { return this.name; }
public static final class Builder {
private String accountId;
private String name;
private Builder() {}
public Builder setAccountId(String accountId) { this.accountId = accountId; return this; }
public Builder setName(String name) { this.name = name; return this; }
public Customer build() { return new Customer(this); }
```
## Describe alternatives you've considered
None
## Additional Context
The restrictions of the current implementation are frustrating because it forces users to name their classes in a specific way.
- [x] I may be able to implement this feature request
## Your Environment
* AWS Java SDK version used: v2
* JDK version used: 11
* Operating System and version: Microsoft Windows 10 Home (10.0.19042 Build 19042)
Contributor guide
Assessment
This issue has not been assessed yet.