首页 > 解决方案 > 子类可以与超类具有相同的列名吗?

问题描述

我已经使用继承映射创建了数据库表。我希望所有表都有审计列。

数据库架构

这是代码:

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Auditable {

    @CreatedDate
    private LocalDateTime createdAt;
    
    @CreatedBy
    private String createdBy;
}
@Entity
@Table(name = "person")
@Inheritance(strategy = InheritanceType.JOINED)
public class Person extends Auditable {

    private String name;
}

@Entity
@PrimaryKeyJoinColumn(name = "person_id")
public class Student extends Person {
   private int grade;
}
@Entity
@PrimaryKeyJoinColumn(name = "person_id")
public class Staff extends Person {
   private int salary;
}

我的问题是只生成了表的created_at和,但表的和为空。created_byPersoncreated_atcreated_byStaffStudent

是否也可以生成created_atand表?created_byStaffStudent

标签: javahibernatejpa

解决方案


您遇到麻烦的原因是因为这是一对一的关联,而不是继承。

此映射不起作用,因为当您使用继承时,您声明 aStudent是 a Person,因此,您创建学生的那一刻就是创建一个人的那一刻。因此,没有理由在表中重复这两个列。

而且,您正在使用InheritanceType.JOINED,基本上要求不在表之间共享公共列。

这种映射有意义的唯一方法是这些列是否代表不同的创建时间。例如,一个人何时出生,何时成为学生。如果是这种情况,您可以使用此映射:

    @Entity
    @PrimaryKeyJoinColumn(name = "person_id")
    public static class Student extends Person {
        int grade;

        @Column(name = "createdAt")
        LocalDateTime studentCreatedAt;

        @Column(name = "createdBy")
        String studentCreatedBy;
    }

    @Entity
    @PrimaryKeyJoinColumn(name = "person_id")
    public static class Staff extends Person {

        int salary;

        @Column(name = "createdAt")
        LocalDateTime staffCreatedAt;

        @Column(name = "createdBy")
        String staffCreatedBy;
    }

如果不是这种情况,则Person不是 and 的超类,StudentStaff可以使用此映射表示您的数据库:

    @Entity
    public class Person extends Auditable {
        @Id
        Long id;
        String name;
    }

    @Entity
    public class Student extends Auditable {
        @Id
        Long id;

        int grade;

        @MapsId
        @OneToOne
        Person person;
    }

    @Entity
    public class Staff extends Auditable {
        @Id
        Long id;

        int salary;

        @MapsId
        @OneToOne
        Person person;
    }

Where@MapsId告诉 Hibernate ORM 该列person_id也是该表的键。因此你不需要@PrimaryKeyJoinColumn(name = "person_id").


推荐阅读