【问题标题】: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 个表。

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

谢谢!

【问题讨论】:

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

标签: java hibernate jpa h2


【解决方案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,它只会将不同的字段添加到每个表中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多