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

Compilation errors on the generated Builder when the @Builder is on private constructor and the toBuilder() is activated. #29

Open
alexandrenavarro opened this issue Nov 10, 2024 · 2 comments

Comments

@alexandrenavarro
Copy link

alexandrenavarro commented Nov 10, 2024

Just for information, when the @builder is on private constructor and the toBuilder() is activated, there are a compilation errors because it tries to instance the builder but it is abstract class.
The builder() method is also not generated.

I don't have any elegant solution, one solution is passing the name of the concrete in the configuration of the annotation.
Think about it if you find a better solution.

Clearly, it is a nice to have fix / feature not a blocking problem.

Thank you for your useful lib and don't hesitate if you have any questions.

@skinny85
Copy link
Owner

skinny85 commented Nov 10, 2024

Thanks for opening the issue @alexandrenavarro.

Thinking about a potential solution, my idea is to add an additional parameter to the static toBuilder() method in the case @Builder was placed on a private method. This new parameter would be of the type of the abstract Builder class, instead of having it created inside the toBuilder() method and stored in a local variable. This should solve the compilation error. And then, in the manually-written class, either write an instance version of toBuilder(), or add a static one to the inner builder class.

So, something like this:

public final class User {
    public final String email, username, firstName, lastName, displayName;

    @Builder(style = BuilderStyle.STAGED, toBuilder = "toBuilder")
    private User(String email, @Opt String username, String firstName,
            String lastName, @Opt String displayName) {
        this.email = email;
        this.username = username == null ? email : username;
        this.firstName = firstName;
        this.lastName = lastName;
        this.displayName = displayName == null
            ? firstName + " " + lastName
            : displayName;
    }

    public final static class InnerBuilder extends UserBuilder {
        private InnerBuilder() {
        }

        @Override
        public User build() {
            return new User(email, username, firstName, lastName, displayName);
        }
    }

    public static UserBuilders.Email builder() {
        return new InnerBuilder();
    }

    public InnerBuilder toBuilder() {
        return UserBuilder.toBuilder(new InnerBuilder(), this);
    }
}

Thoughts on this idea?

@alexandrenavarro
Copy link
Author

It seems a good solution.

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