0

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!

2 Answers2

1

Annotating both the parent and the child class with @SuperBuilder should be one way to make all attributes available:

fladdimir
  • 1,230
  • 1
  • 5
  • 12
  • 1
    Thank you but now when I build my project I am getting this Error: java cannot find symbol class abstractpersistable builder –  Dec 03 '21 at 20:51
1

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.

pirho
  • 11,565
  • 12
  • 43
  • 70
  • 1
    thanks I am going with the @SuperBuilder; however, now I am getting this Error(`cannot find symbol class AbstractPersistableBuilder`) when building the project –  Dec 03 '21 at 20:50
  • @user17441315 I believe this error has not much to do with Lombok but something like incomplete clean before build and/or problem with your imports. – pirho Dec 04 '21 at 08:53
  • It does. Because when using `@SuperBuilder` all parent and child classes have to be mapped also as `@SuperBuilder`. But thanks! –  Dec 06 '21 at 12:59