kentsurrey
kentsurrey

Reputation: 500

How to use Lombok's toBuilder on @SuperBuilder

Currently I have these three classes:

@Value
@NonFinal
@SuperBuilder
public class Parent {
    // Some fields
}

@Value
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
public class ChildA extends Parent {
    // Some fields
}

@Value
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
public class ChildB extends Parent {
    // Some fields
}

I want to use it in a mapper as follows to avoid duplicating any code:

private ChildA buildChildA(Entity entity) {
    Parent parent = ((ChildB) buildParent(entity, ChildA.builder().build()))
        .toBuilder()
        // Populate Child A fields from entity
        .build();
}

private ChildB buildChildB(Entity entity) {
    Parent parent = ((ChildA) buildParent(entity, ChildA.builder().build()))
        .toBuilder()
        // Populate Child B fields from entity
        .build();
}

private Parent buildParent(Partner entity, Parent parent) {
    return parent.toBuilder()
        // Populate Parent fields here
        .build();
}

However when I try to compile I get:

ChildA.java:13: error: method does not override or implement a method from a supertype 
@SuperBuilder(toBuilder = true) 
^ 
ChildB.java:13: error: method does not override or implement a method from a supertype 
@SuperBuilder(toBuilder = true) 
^ 
2 errors

How do you use toBuilder with @SuperBuilder? I'm using lombok v1.18.4.

Upvotes: 22

Views: 12187

Answers (1)

Jan Rieke
Jan Rieke

Reputation: 8052

If you want to use @SuperBuilder with toBuilder, all classes in the hierarchy must have toBuilder=true. The reason is that the toBuilder() method only copies the field values from its respective class, but delegates the copying of the field values from the supertypes to the supertypes' toBuilder() methods.

So just add toBuilder=true to your Parent class, too.

Upvotes: 35

Related Questions