I have these two classes with lombok Annotations:
@Data
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Parent {
private String id
private Long field1;
private Long field2;
private Long field3;
}
and
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Child extends Parent {
private Integer prop1;
private Integer prop2;
private Integer prop3;
}
I would like to use an existent Parent instance to create a child instance, with all parent fields filled, and be able to complement with child properties (like Child.fromParent(parent).prop1(10).build()).
Is there a way to do it with lombok features, instead of a parent's "field by field" solution ?
I have these two classes with lombok Annotations:
@Data
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Parent {
private String id
private Long field1;
private Long field2;
private Long field3;
}
and
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Child extends Parent {
private Integer prop1;
private Integer prop2;
private Integer prop3;
}
I would like to use an existent Parent instance to create a child instance, with all parent fields filled, and be able to complement with child properties (like Child.fromParent(parent).prop1(10).build()).
Is there a way to do it with lombok features, instead of a parent's "field by field" solution ?
Share Improve this question edited Mar 17 at 14:11 Ricardo Henrique Comar asked Mar 17 at 13:48 Ricardo Henrique ComarRicardo Henrique Comar 135 bronze badges1 Answer
Reset to default 1You can indeed reuse some of the code that Lombok generates. In particular, Lombok generates a static method called $fillValuesFromInstanceIntoBuilder
, which takes an instance and a builder, and populates the builder with the properties in the instance. This method is private
, so you need to write a public wrapper around that.
@Data
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Parent {
private String id;
private Long field1;
private Long field2;
private Long field3;
public static abstract class ParentBuilder<C extends Parent, B extends ParentBuilder<C, B>> {
public static void fillValuesFromInstanceIntoBuilder(Parent instance, ParentBuilder<?, ?> b) {
$fillValuesFromInstanceIntoBuilder(instance, b);
}
}
}
Then you can write a fromParent
in Child
like this:
public static ChildBuilder<?, ?> fromParent(Parent parent) {
var childBuilder = new ChildBuilderImpl();
ParentBuilder.fillValuesFromInstanceIntoBuilder(parent, childBuilder);
return childBuilder;
}
It is important to note that if you pass an instance of Child
to fromParent
, only the Parent
fields will be copied to the builder. The fields specific to Child
will be ignored.