Search code examples
javaspringlombokintellij-lombok-plugin

Lombok @SuperBuilder is not initializing my class objects


I have a parent class and a child class and I am using @SuperBuilder to build the child object, but seemingly it is not initializing at all. My parent class looks like this:

@Getter
@Setter
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@SuperBuilder
public class MessageResponse {
    String responseMessage;
}

My child class looks like this:

@Getter
@Setter
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@SuperBuilder
public class ListResponse extends MessageResponse {
    List<Item> itemList;
    int itemCount;
}

Where Item is a Serializable class.

Initially the ListResponse is

itemList = null
itemCount = 0
responseMessage = null

When I try to build ListResponse using builder, it does not change the ListResponse object at all. I am trying to build as

//listResponse is @Autowired from Spring and is initially as shown above. 
List<Item> itemList = getItems(); // It returns a list of 15 items, i have checked in debugger, It does.
listResponse.builder()
        .bucketList(itemList)
        .responseMessage("Item List.")
        .bucketCount(itemList.size())
        .build();

Even after execution of .build() the contents of this listResponse object is still (null, 0 , null).

I tried to search other references regarding @SuperBuilder and @Builder but got no result. Can someone please point out what is going wrong here?


Solution

  • A builder always creates a new instance. This is the purpose of the builder pattern, and it is how builders work, whether you use Lombok's @SuperBuilder, @Builder, or a manual builder implementation.

    You can see that the builder() method is a static method, so it has no access to the instance (typically your IDE should give you a warning here, advising to write ListResponse.builder() instead).

    If you want to create a new instance using a builder that is pre-filled with the fields from an existing instance, you can use toBuilder = true as annotation parameter on @(Super)Builder. Then call listResponse.toBuilder().

    If you want to modify an instance, the builder pattern is not the right choice. Use setters instead. Those can be generated by Lombok also in a fluent, chainable style; see @Accessors for details.