使用休眠保持基类和子类
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,它只会将不同的字段添加到每个表中。以上是关于使用休眠保持基类和子类的主要内容,如果未能解决你的问题,请参考以下文章