5

我有以下 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表。我有大量的 JPA 实体,我希望 bookkeepingparent 成为其中大多数实体的超类。这主要是因为一些非常具体的 ID 生成策略和其他簿记活动。这种设计有助于将本书中的所有代码与功能代码分开,并让处理功能代码的程序员不必担心。

在桌子数量增加之前,所有这些都可以正常工作。现在我们看到,对于所有ManyToOneOneToOne关系,JPA 正在生成引用父表的外键。对于 200 个奇数表,插入已经很慢,因为所有外键约束都引用 bookekeepingparent,并且每个实体在第一次持久化时都会插入到 bookkeeping 父表中。我猜这是检查大约 150 个奇怪的约束。

所以,以下是我的问题:JPA 为什么要这样做?这是标准的 JPA 行为吗?(我正在使用 EclipseLink)如果我手动更改数据库架构,他们会遇到什么陷阱吗?

这是我在 StackOverflow 上的第一个问题,我尽力搜索任何现有的答案。抱歉,如果我错过了任何内容。谢谢。

4

1 回答 1

1

您正在使用联合继承,这意味着对于每个类,bookkeepingparenttable 是主表,任何子类表都是辅助表。子类的主键是从父类继承的,外键必须引用id,所以在设计上都会引用bookkeepingparenttable中的id。不同的提供者允许引用非 pk 字段,但它可能会导致问题,因为解析引用可能需要数据库命中而不是使用缓存。

数据库约束与 JPA 无关,因此您可以根据需要更改它们,只要插入更新和删除仍然符合要求,就不会影响应用程序。

于 2013-06-09T02:15:29.243 回答