我有以下 JPA 2.0 实体
@Entity
@Inheritance(strategy= InheritanceType.JOINED)
public abstract class BookKeepingParent implements Serializable {
@Id
protected Long Id;
...
}
@Entity
public class Employee extends BookKeepingParent {
private String name;
@ManyToOne
private Role role;
...
}
@Entity
public class Role extends BookKeepingParent {
private String name;
...
}
我想让 JPA 为我生成表,因为它可以更轻松地在多个位置安装。我通常会期望它产生这个:
CREATE TABLE bookkeepingparent (
id bigint NOT NULL,
dtype character varying(31),
CONSTRAINT bookkeepingparent_pkey PRIMARY KEY (id )
)
CREATE TABLE role (
id bigint NOT NULL,
name character varying(255),
CONSTRAINT role_pkey PRIMARY KEY (id ),
CONSTRAINT fk_role_id FOREIGN KEY (id) REFERENCES bookkeepingparent (id)
)
CREATE TABLE employee (
id bigint NOT NULL,
name character varying(255),
role_id bigint,
CONSTRAINT employee_pkey PRIMARY KEY (id ),
CONSTRAINT fk_employee_id FOREIGN KEY (id) REFERENCES bookkeepingparent (id),
CONSTRAINT fk_employee_role_id FOREIGN KEY (role_id) REFERENCES role (id)
)
前两个表在哪里相同,但它生成了
employee
这样表:CREATE TABLE employee (
id bigint NOT NULL,
name character varying(255),
role_id bigint,
CONSTRAINT employee_pkey PRIMARY KEY (id ),
CONSTRAINT fk_employee_id FOREIGN KEY (id) REFERENCES bookkeepingparent (id),
CONSTRAINT fk_employee_role_id FOREIGN KEY (role_id) REFERENCES bookkeepingparent (id)
)
您可以注意到
fk_employee_role_id
引用 bookkeepingparent
表,而不是 role
table 。我有一个很大的 JPA 实体层次结构,我希望 bookkeepingparent 成为其中大多数实体的父类(super class)。这主要是因为一些非常具体的 Id 生成策略和其他簿记事件。这种设计有助于保持本书的所有代码与功能代码分开,让程序员在处理功能代码时不必担心。所有这些工作正常,直到表的数量增加。现在我们看到,对于所有
ManyToOne
和 OneToOne
关系,JPA 正在生成引用父表的外键。对于 200 个奇数表,插入已经很慢,因为所有外键约束都引用了簿记父表,并且每个实体在第一次持久化时都会插入到簿记父表中。我猜这是检查大约 150 个奇怪的约束。所以,以下是我的问题:JPA 为什么要这样做?这是标准的 JPA 行为吗? (我正在使用 EclipseLink)如果我手动更改数据库架构,他们是否会遇到任何陷阱?
这是我在 StackOverflow 上的第一个问题,我尽力搜索任何现有的答案。如有遗漏,请见谅。谢谢。
最佳答案
您正在使用连接继承,这意味着对于每个类,bookkeepingparenttable 是主表,任何子类表都是次要的。子类的主键是从父类继承的,外键必须引用id,所以设计时都会引用bookkeepingparenttable中的id。不同的提供者允许引用非 pk 字段,但它可能会导致问题,因为解析引用可能需要数据库命中而不是使用缓存。
数据库约束与 JPA 无关,因此您可以根据需要更改它们,只要插入更新和删除仍然符合,就不会影响应用程序。
关于jpa - 在使用 InheritanceType.JOINED 的 JPA 实体层次结构中,与子类的所有关系都会导致父类(super class)表上的外键约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16985779/