Home > Enterprise >  JPA inheritance strategy JOINED: Connot access superclass attributes
JPA inheritance strategy JOINED: Connot access superclass attributes

Time:12-04

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:

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.

  • Related