JPA 继承策略已加入:无法访问超类属性

Posted

技术标签:

【中文标题】JPA 继承策略已加入:无法访问超类属性【英文标题】:JPA inheritance strategy JOINED: Connot access superclass attributes 【发布时间】:2022-01-10 02:17:02 【问题描述】:

我正在做一个项目,我必须实现一个类层次结构。例如,典型的 Person 层次结构。

我有一个抽象超类Person 及其子类Student

超类

@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;
    
    // ...


子类学生

@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "students")
public class Student extends Person 
    @Getter
    private int grade;

    // ...


问题

我的问题是我在使用.builder() 时无法访问超类的属性。

Student student =
         Student.builder()
                .name("UniqueName") //CompilerError(Cannot resolve method 'name' in 'StudentBuilder')
                .age(19)
                .grade(2)
                .build();

但是,当我从超类 Person 中删除 @Builder 时,我只能访问超类的属性,而不能访问子类的属性。 而当我从子类中移除 @Builder 并将其保留在超类中时,情况正好相反。

我的问题是我做错了什么 - 我相信这是因为 @Builder 注释,@Builder 的正确表示是什么

提前致谢!

【问题讨论】:

【参考方案1】:

你有两个选择。要么创建调用父构造函数的构建器构造函数,所以类似于:

@Builder
public Student(String name, int age, int grade) 
    super(name, age);
    this.grade = grade;

在您的学生中(并删除班级级别的@Builder)。您还需要将Person@AllArgsConstructor 的可见性至少扩展到受保护。见this。

另一种选择是使用 Lombok @SuperBuilder(实验包,但似乎有效)。只需将两个班级中的@Builder 替换为@SuperBuilder

【讨论】:

谢谢我和@SuperBuilder一起去;但是,现在我在构建项目时遇到此错误(cannot find symbol class AbstractPersistableBuilder @user17441315 我相信这个错误与 Lombok 没有太大关系,而是像构建前不完整的清理和/或导入问题。 确实如此。因为在使用@SuperBuilder 时,所有父类和子类也必须映射为@SuperBuilder。不过谢谢!【参考方案2】:

使用@SuperBuilder 注释父类和子类应该是使所有属性可用的一种方法:

https://projectlombok.org/features/experimental/SuperBuilder Lombok @builder on a class that extends another class

【讨论】:

谢谢,但是现在当我构建我的项目时,我收到了这个错误:java 找不到符号类 abstractpersistable builder

以上是关于JPA 继承策略已加入:无法访问超类属性的主要内容,如果未能解决你的问题,请参考以下文章

JPA实体继承实体的映射策略

Java中的间接子类无法访问的超类中的受保护成员

无法从超类访问 Django 模型的子类

PHP继承的父方法无法访问孩子的私有属性

当子类使用Object变量实例化时,无法从超类访问方法

hibernate.jpa.criteria.BasicPathUsageException:无法加入基本类型的属性