我想定义一个对象模型如下:
A 包含 X 的列表,每个 X 都包含一个 Y,每个 Y 都指一个 B。我已经将 A 和 B 设置为Entity
,并且 X 和 Y 都是Embeddable
。A 包含@ElementCollection
X 类型的列表。这些类的代码如下。
当要求 Hibernate (3.6.10) 使用 为这个模型生成 SQL 时SchemaExport
,我期望三个表:A、B 和一个用于从 A 到 B 的引用的集合表,其中包含 A.id、B.id 和用于保持列表顺序的顺序列。相反,Hibernate 给了我以下内容:
create table CollectionOfB (A_ID bigint not null, embeddableAList_ORDER integer not null, primary key (A_ID, embeddableAList_ORDER))
create table EntityA (id bigint not null, primary key (id))
create table EntityB (id bigint not null, primary key (id))
alter table CollectionOfB add constraint FKFEABC9AD9AECF0BB foreign key (A_ID) references EntityA
请注意,集合表没有 B.id 列,也没有应有的外键约束。在我看来,我想要的模型应该得到支持。它是否有充分的理由不起作用(如果是,那是什么原因?),或者这是 Hibernate 或 JPA 中的错误/缺失功能?
作为一个实验,我折叠了我的Embeddable
关系,所以它只有一个级别(完全删除 Y,将对 B 的引用放在 X 中)。有了这个改变,模式就如我所料地生成了,所以有一个ElementCollection
where the Embeddable
has a的基本想法是ManyToOne
有效的:
create table CollectionOfB (A_ID bigint not null, B_ID bigint, embeddableAList_ORDER integer not null, primary key (A_ID, embeddableAList_ORDER))
create table EntityA (id bigint not null, primary key (id))
create table EntityB (id bigint not null, primary key (id))
alter table CollectionOfB add constraint FKFEABC9AD9AED651B foreign key (B_ID) references EntityB
alter table CollectionOfB add constraint FKFEABC9AD9AECF0BB foreign key (A_ID) references EntityA
此外,如果我制作了一个不同的Entity
C,并将其定义为具有Embeddable
X(不是X的一个ElementCollection
),则它正确地引用了 B。因此,Embeddable
在较低级别具有 a 的地方具有两个级别的想法ManyToOne
也有效。
@Embeddable
public class EmbeddedX {
// Comment out to "collapse" X and Y
@Embedded
EmbeddedY embeddedY;
// Comment in to "collapse" X and Y
// @JoinColumn(name = "B_ID")
// @ManyToOne(fetch = FetchType.EAGER)
// EntityB entityB;
}
@Embeddable
public class EmbeddedY {
@JoinColumn(name = "B_ID")
@ManyToOne(fetch = FetchType.EAGER)
EntityB entityB;
}
@Entity
public class EntityA {
@Id
Long id;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "CollectionOfB", joinColumns = @JoinColumn(name = "A_ID"))
@Column(name = "Bs")
@OrderColumn
List<EmbeddedA> embeddableAList;
}
@Entity
public class EntityB {
@Id
Long id;
}
public void testSchema() throws Exception {
Configuration config = new Configuration().addAnnotatedClass(EntityA.class).addAnnotatedClass(EntityB.class);
config.setProperty(Environment.DIALECT, HSQLDialect.class.getName());
new SchemaExport(config).create(true, false);
}