@Builder - combining builders

336 views
Skip to first unread message

Guy

unread,
Jul 12, 2019, 6:48:22 AM7/12/19
to Project Lombok
I would like combine builders like:


Avoiding the need to call build() on every nested object and making my code a bit cleaner i.e. passing another builder into property on a builder and that calling build.

Is this currently possible?

Thanks,

Guy

Reinier Zwitserloot

unread,
Jul 13, 2019, 5:21:29 AM7/13/19
to Project Lombok
If I read this correctly, what you're asking for is an overloaded method in a generated builder. So, instead of generating, say:

     PersonBuilder address(Address address) { this.address = address; return this; }

we generate that AND In addition, ALSO:

    PersonBuilder address(Address.AddressBuilder addressBuilder) {this.address = address.build(); return this; }

and for singulars, a similar approach.

There are some major problems there: the name of the builder type is configurable, so it's hard for us to know that it's 'Address.AddressBuilder'. More importantly, there's absolutely no way for us to know that Address -HAS- a builder like this. See https://github.com/rzwitserloot/lombok/wiki/LOMBOK-CONCEPT:-Resolution for why this is hard to do.

What we can do is something like:

    @Builder @Value
    public class Person {
        @CombineBuilder Address address;
    }

which would presume the 'standard' strategy for naming the builder (which depends first on an explicit parameter in @Builder, then on lombok.config, and finally _TypeName_Builder). Alternatively:

    @Builder @Value
    public class Person {
        @CombineBuilder(AddressBuilder.class) Address address;
    }

but note that when you use the name 'combine builder' I'm thinking about taking the individual bits of Address and adding those straight in. So, assuming AddressBuilder has a .street() method, that person itself gets .street, so that you can do:

    Person.builder()
        .name("Jane Abrahamson") // this ends up setting a field in Person
        .street("Main Street") // this ends up being passed into the address builder
        .build()

and doing that would be impossible without either [A] reflection or [B] a requirement that the Address class is in the same source file as the Person class so that we can introspect on it during compilation phase without requiring resolution trickery.

So.. given that I really don't want to waste the combine name on this.... anyone have a good idea about a name? More generally does this feature stand any chance? I don't think 'we complicate the lombok side of things both in our implementation and our manuals and learning curve, and all you get in return is that you can omit build() calls' is worth it in the first place. Now, that combining builder notion, maybe that's got legs, but implementing that is really hard due to requiring either resolution or unacceptably tight limits like 'all relevant classes must be in the same source file'.

So, sounds like a non-starter but perhaps I'm missing some tricks to make this simpler.


Jan Matèrne (GMail)

unread,
Jul 13, 2019, 8:05:22 AM7/13/19
to project...@googlegroups.com

You could easily use @Setter(AccessorType=FLUENT)

 

With just passing values to a nested builder doesn't work if you have muliple nested objects:

 

class Person {

  String name, prename;

   List<Adress> adresses;

}

 

Person.builder()

    .name("Trump")

    .street("White House")

   .street("Trump Tower")

    .prename("Donald")

    .number("42")

   .number("1")

   .build();

 

Where does the "42" belongs to?

 

 

Jan

 

 

--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/2ba69732-9546-487d-a0d4-00f6f0ef0670%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reinier Zwitserloot

unread,
Jul 15, 2019, 5:06:21 PM7/15/19
to Project Lombok
That kind of 'combination' + singular obviously cannot work.

To unsubscribe from this group and stop receiving emails from it, send an email to project-lombok+unsubscribe@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages