In my project, I am using lombok to avoid writing getters and setters for a class. Also, I am using lombok.Builder to build an object instead of writing new Obeject() and then setting all the values.
But when we have inheritance relationship and when we want to construct child object using lombok builder, I am not getting parent's field.
For example:
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class Parent{
private String nationality;
.
.
// more columns
}
And Child class would be something like this:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Child extends Parent{
private String firstName;
private String lastName;
.
.
}
In my test class, where I need to build child object
public class Test{
public void testMethod(){
Child child = Child.builder()
.firstName("Rakesh")
.lastName("SS")
.nationality("some text")// I am not able to set nationality
.build();
}
}
Please let me know, is there any way to handle this scenario in lombok.
Make a generic builder for each class that will have a subclass builder. This builder will already contain the setter methods for the current class, but we create also a second non generic builder for the class that contains the constructor and build method. The builders will not have any fields.
The @SuperBuilder annotation produces complex builder APIs for your classes. In contrast to @Builder , @SuperBuilder also works with fields from superclasses. However, it only works for types. Most importantly, it requires that all superclasses also have the @SuperBuilder annotation.
Martin GrajcarYour @Builder needs an @AllArgsConstructor (add it; feel free to make it private).
An all new drag-and-drop page builder The Super Builder is a new tool for creating sleek landing pages right in Notion. Simply drag and drop components into place and change the content until you are happy. Then you can save out your page and turn into a live site using Super.
@Builder
has no way to determine which fields of Parent
you wish to expose.
When @Builder
is placed on a class, only fields explicitly declared on that class are added to the *Builder
.
When @Builder
is placed on a static method or a constructor the resulting *Builder
will have a method for each argument.
Also if you are using @Builder
then is it safe to assume that at least Child
is meant to be immutable?
I supply two examples, one where Parent
is mutable and Child
is immutable and one where both Parent
and Child
are immutable.
import static org.junit.Assert.*;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
import lombok.experimental.NonFinal;
import org.junit.Test;
public class So32989562ValueTest {
@Value
@NonFinal
public static class Parent {
protected final String nationality;
}
@Value
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static class Child extends Parent {
private final String firstName;
private final String lastName;
@Builder(toBuilder = true)
private Child(String nationality, String firstName, String lastName) {
super(nationality);
this.firstName = firstName;
this.lastName = lastName;
}
}
@Test
public void testChildBuilder() {
String expectedFirstName = "Jeff";
String expectedLastName = "Maxwell";
String expectedNationality = "USA";
Child result = Child.builder()
.firstName(expectedFirstName)
.lastName(expectedLastName)
.nationality(expectedNationality)
.build();
assertEquals(result.toString(), expectedFirstName, result.getFirstName());
assertEquals(result.toString(), expectedLastName, result.getLastName());
assertEquals(result.toString(), expectedNationality, result.getNationality());
}
}
import static org.junit.Assert.*;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
import org.junit.Test;
public class So32989562DataTest {
@Data
public static class Parent {
protected String nationality;
}
@Value
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static class Child extends Parent {
private final String firstName;
private final String lastName;
@Builder(toBuilder = true)
private Child(String nationality, String firstName, String lastName) {
this.setNationality(nationality);
this.firstName = firstName;
this.lastName = lastName;
}
}
@Test
public void testChildBuilder() {
String expectedFirstName = "Jeff";
String expectedLastName = "Maxwell";
String expectedNationality = "USA";
Child result = Child.builder()
.firstName(expectedFirstName)
.lastName(expectedLastName)
.nationality(expectedNationality)
.build();
assertEquals(result.toString(), expectedFirstName, result.getFirstName());
assertEquals(result.toString(), expectedLastName, result.getLastName());
assertEquals(result.toString(), expectedNationality, result.getNationality());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With