我有一个实体映射如下:
@Entity
@Table(name = "Groups")
@IdClass(value = GroupId.class)
public class Group implements Serializable
{
@Id
@Column(name = "round_id")
private Integer roundId;
@Id
@Column(name = "ordinal_nbr")
private Integer ordinalNbr = 0;
...
}
它有一个组合键
(round_id, ordinal_nbr)
,用于指示轮次中组的顺序。现在想象一个连接表,包含通过自引用(从Group到Group)链接有序组的实体:
CREATE TABLE GroupLinks
(
parent_round_id INTEGER NOT NULL,
parent_ordinal_nbr SMALLINT NOT NULL,
child_round_id INTEGER NOT NULL,
child_ordinal_nbr SMALLINT NOT NULL,
PRIMARY KEY (parent_round_id, parent_ordinal_nbr, child_round_id, child_ordinal_nbr),
FOREIGN KEY (parent_round_id, parent_ordinal_nbr) REFERENCES Groups (round_id, ordinal_nbr),
FOREIGN KEY (child_round_id, child_ordinal_nbr) REFERENCES Groups (round_id, ordinal_nbr)
);
我知道可以为拥有实体(无论我选择哪个)映射@ManyToMany
+@JoinTable
+@OrderColumn
:
@ManyToMany
@JoinTable(name = "GroupLinks", joinColumns = {@JoinColumn(name = "parent_round_id", referencedColumnName = "round_id"), @JoinColumn(name = "parent_ordinal_nbr", referencedColumnName = "ordinal_nbr")}, inverseJoinColumns = {@JoinColumn(name = "child_round_id", referencedColumnName = "round_id"), @JoinColumn(name = "child_ordinal_nbr", referencedColumnName = "ordinal_nbr")})
@OrderColumn(name = "child_ordinal_nbr")
private List<Group> children;
问题:
对于拥有方,是否支持使用@OrderColumn
来映射@ManyToMany(mappedBy = ...)
的反向关系?
@ManyToMany(mappedBy = "parents")
@OrderColumn(name = "parent_ordinal_nbr")
private List<Group> parents;
JPA 2规范是否允许或拒绝此操作? 谢谢。
更新1:
以上基本上是一个图形结构。这里有一个例子:
GroupLinks
表包含方框实体。只看B2 Group
实体时,parents
列表将包含(a,1,b,2)
和(a,2,b,2)
。至于children
列表,则会包含(b,2,c,1)
、(b,2,c,2)
和(b,2,c,3)
。如您所见,
B2
列表中的实体不会发生冲突,因此@OrderColumn
对于parents
和children
两个关系都可以正常工作-至少在理论上是这样。但是在这里(JPA)的实践是什么呢?请注意,仅在Hibernate和/或EclipseLink上尝试并不能真正回答这个问题,即JPA 2规范或JPA兼容提供程序是否应该或必须支持此场景。
更新2:
尝试在Hibernate上使用以上映射会导致以下映射异常:
Caused by: org.hibernate.MappingException: Repeated column in mapping for collection: com.kawoolutions.bbstats.model.Group.parents column: parent_ordinal_nbr
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:340)
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:363)
at org.hibernate.mapping.Collection.validate(Collection.java:320)
at org.hibernate.mapping.IndexedCollection.validate(IndexedCollection.java:89)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1291)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1729)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:84)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
... 9 more
移除@OrderColumn
中的parent_ordinal_nbr
会导致children
关系出现相同的异常。看起来Hibernate不喜欢同时用于外键的排序列。
更新3:
在GlassFish上使用EclipseLink测试过,这个方法可行,没有映射异常。
这引出了两个后续问题:
- JPA是否禁止外键列的顺序?我不明白为什么它们不能正常工作...
- 这是Hibernate的一个bug吗?