使用休眠保持基类和子类

Posted

技术标签:

【中文标题】使用休眠保持基类和子类【英文标题】:Persist base and subclass with hibernate 【发布时间】:2018-08-25 19:50:13 【问题描述】:

我目前正在尝试自己构建一个带有 jdbc 连接的完整 Spring Boot Rest 服务。

目前,我正在努力解决有关休眠和存储实体的小问题。

我有一个基类:

@Entity
@Table
public abstract class Person 

  private int id;
  private String firstName;
  private String middleName;
  private String lastName;

  @Id
  @GeneratedValue(generator = "increment")
  @GenericGenerator(name = "increment", strategy = "increment")
  public int getId() 
    return id;
  

  public void setId(int id) 
    this.id = id;
  

  @Column
  public String getFirstName() 
    return firstName;
  

  public void setFirstName(String firstName) 
    this.firstName = firstName;
  

  @Column
  public String getMiddleName() 
    return middleName;
  

  public void setMiddleName(String middleName) 
    this.middleName = middleName;
  

  @Column
  public String getLastName() 
    return lastName;
  

  public void setLastName(String lastName) 
    this.lastName = lastName;
  

还有2个子类:

@Entity
@Table
public class Member extends Person

  private String memberNumber;

  @Column
  public String getMemberNumber() 
    return memberNumber;
  

  public void setMemberNumber(String memberNumber) 
    this.memberNumber = memberNumber;
  

@Entity
@Table
public class Supporter extends Person 

  private String supporterNumber;

  @Column
  public String getSupporterNumber() 
    return supporterNumber;
  

  public void setSupporterNumber(String supporterNumber) 
    this.supporterNumber = supporterNumber;
  

基类是抽象的,因为我想防止在不指定成员或支持者的情况下创建它的实例。但在数据库方案中,由于规范化,我仍然希望有 3 个表。

我现在应该使用哪些注释来达到这个目标?我现在如何将一行成员或支持者链接到该成员?我真的很困惑。

谢谢!

【问题讨论】:

欢迎使用***,您能与我们分享您遇到了什么错误吗? 直到现在我没有收到任何错误信息。我只是想了解下一步我要做什么。 :) 为什么不查看任何有关“继承”的在线 JPA 文档?他们告诉你所有你需要知道的。 我已阅读所有文档和教程。对于我的问题,我没有得到答案。我认为在上面的这个例子中我无法想象。 【参考方案1】:

类到表的映射是由hibernate完成的。由于关系数据库表和 Java 对象是不同的 ORM 映射器,因此它们之间的映射策略不同。

Hibernate 可以使用以下策略:

映射超类 单表(默认) 联表 每类表

您可以通过official documentation 了解更多信息。

它们各有优缺点,通常只使用默认值是最安全的。但是默认策略只使用一个表,因此您需要切换到其他策略。

每个类的表将创建三个表。您还可以查看 MappedSuperclass 和 Joined Table 的示例,它们也将使用多个表。

来自官方文档:

@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public static class Account 
    @Id
    private Long id;
    private String owner;
    private BigDecimal balance;
    private BigDecimal interestRate;
    //Getters and setters are omitted for brevity


@Entity(name = "DebitAccount")
public static class DebitAccount extends Account 
    private BigDecimal overdraftFee;
    //Getters and setters are omitted for brevity


@Entity(name = "CreditAccount")
public static class CreditAccount extends Account 
    private BigDecimal creditLimit;
    //Getters and setters are omitted for brevity

将创建这些表:

CREATE TABLE Account (
    id BIGINT NOT NULL ,
    balance NUMERIC(19, 2) ,
    interestRate NUMERIC(19, 2) ,
    owner VARCHAR(255) ,
    PRIMARY KEY ( id )
)

CREATE TABLE CreditAccount (
    id BIGINT NOT NULL ,
    balance NUMERIC(19, 2) ,
    interestRate NUMERIC(19, 2) ,
    owner VARCHAR(255) ,
    creditLimit NUMERIC(19, 2) ,
    PRIMARY KEY ( id )
)

CREATE TABLE DebitAccount (
    id BIGINT NOT NULL ,
    balance NUMERIC(19, 2) ,
    interestRate NUMERIC(19, 2) ,
    owner VARCHAR(255) ,
    overdraftFee NUMERIC(19, 2) ,
    PRIMARY KEY ( id )
)

【讨论】:

首先谢谢。但是我不明白为什么有 3 个未规范化的表。为什么派生类的字段与基类的字段相同?我想要的只是一个规范化的结构,而不是将一个人实例化为成员或支持者类中的实例变量。 所以只需使用其他策略,例如 JOINED,它只会将不同的字段添加到每个表中。

以上是关于使用休眠保持基类和子类的主要内容,如果未能解决你的问题,请参考以下文章

基类和子类函数名相同且参数类型一样,基类函数如何被覆盖,还存在吗?存在何处?请详细回答,谢谢~~~~

带有基类和子类的 Python 单元测试

Swift:如何检查子类上的基类和超类

正确包含基类和子类(派生类)的头文件?

java中基类和子类的类型是一样的吗?

基类和派生类 小知识点