Skip to content
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

[FEATURE] Allow use of @Builder with only a toBuilder() method and no @Builder.Default warnings #2046

Closed
BVollmerhaus opened this issue Feb 20, 2019 · 2 comments

Comments

@BVollmerhaus
Copy link

BVollmerhaus commented Feb 20, 2019

Current Functionality

Lombok's @Builder annotation always adds a builder() method to the annotated class, which can be used to easily create instances with specific values using a fluent interface.

This annotation was later extended with a toBuilder parameter which causes Lombok to also generate a toBuilder() method. This method returns a builder based on the object's current attribute values. A practical usage of this that we use extensively in our entities is to very easily provide a shallow-clone for objects by annotating the class with @Builder(toBuilder = true) and calling toBuilder().build() to get a shallow-cloned instance.

A separate @CopyConstructor annotation has previously been denied with the reasoning that the above pattern is entirely sufficient for performing shallow clones (which is indeed the case).

Our Use Case

We'd like to continue using toBuilder like this to shallow-clone objects; however, the fact that Lombok warns on every single "missing" @Builder.Default annotation is quite annoying. @Builder.Default does not make a lot of sense in combination with toBuilder, as the latter method already copies over the contents of all fields regardless of their initializer.

Imagine the following field in an entity class:

private Set<UserEntity> affectedUsers = new HashSet<>();

When the class is annotated with @Builder, Lombok will produce a warning for the above field stating that it will not be initialized when not explicitly set in a builder call like:

MainEntity.builder().affectedUsers(...).build()

This makes sense with standard builder classes, however on classes that are only used with toBuilder to provide easy cloning, warnings on such fields do not make sense, since toBuilder() simply copies over all values from the existing instance anyway, including the already initialized field in the example.

Proposal

Therefore I'd like to propose a parameter onlyToBuilder or something similar for the @Builder annotation, which

  • leads to no builder() method being added and
  • no warning being produced for fields with default initializers but no @Builder.Default annotation.

This would allow us to continue using toBuilder() to easily perform shallow clones, but not

  1. add an unused builder() method and
  2. spam the compile output with Builder.Default warnings.
@rzwitserloot
Copy link
Collaborator

That feels far too exotic; it breaks the 'it's a parameter party!' rule (which is: If accepting all feature requests of similar exoticness as this one, does the lombok annotation end up having many tens of parameters? Then deny the feature request).

However, I do see the painpoint, I just don't know how to address it without making the annotation grow a few too many parameters.

What about this:

We make it legal to write @Builder(builderMethodName = ""), and we interpret this to mean: Don't make that method at all.

Additionally, if we don't make a builder() method, either because of the above setting, or because you already wrote one yourself, we skip the step where we emit those missing @Default annotation warnings?

@rzwitserloot
Copy link
Collaborator

Liked your idea (+ my tweak) so much, added. Will be in next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants