I am working on a project and I have to implement a class hierarchy. For example, a typical Person hierarchy.
I have an abstract superclass Person
and its subclasses Student
.
Superclass Person:
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(
name = "persons"
uniqueConstraints = {
@UniqueConstraint(name = "persons_name_unique", columnNames = "name")
})
public abstract class Person extends AbstractPersistable<Long>{
@Getter
private String name;
@Getter
private int age;
// ...
}
Subclass Student:
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "students")
public class Student extends Person {
@Getter
private int grade;
// ...
}
Problem:
My issue is that I cannot access the attributes of the superclass when I am using the .builder()
.
Student student =
Student.builder()
.name("UniqueName") //CompilerError(Cannot resolve method 'name' in 'StudentBuilder')
.age(19)
.grade(2)
.build();
However, when I remove @Builder
from the superclass Person
I can access only the attributes of the superclass and none of the subclass.
And when I romove @Builder
from the subclass and keep it in the superclass it's the other way around.
My question is what am I doing wrong - I believe it's because of the @Builder
annotation, what's the correct representation of @Builder
Thanks in Advance!
CodePudding user response:
Annotating both the parent and the child class with @SuperBuilder
should be one way to make all attributes available:
- https://projectlombok.org/features/experimental/SuperBuilder
- Lombok @builder on a class that extends another class
CodePudding user response:
You have two options. Either create builder constructor that calls the parent constructor, so something like:
@Builder
public Student(String name, int age, int grade) {
super(name, age);
this.grade = grade;
}
in your student (and remove the class level @Builder). You also need to expand visibility of Person
@AllArgsConstructor
at least to to protected. See this.
Another option is to use Lombok @SuperBuilder
(package experimental but seems to works). Just replace @Builder
in both of your classes with @SuperBuilder
.