1

我正在使用 EclipseLink 2.4.0,并试图找到一种方法来生成以下 DDL 语句:

ALTER TABLE DELTA ADD CONSTRAINT DELTAFK1 FOREIGN KEY (APPKEY, NEWREVISION) REFERENCES REVISION (APPKEY, REVISION);
ALTER TABLE DELTA ADD CONSTRAINT DELTAFK2 FOREIGN KEY (APPKEY, OLDREVISION) REFERENCES REVISION (APPKEY, REVISION);

DELTA 表中的每一行代表两个指定修订版本之间的更改,主键由 APPKEY、NEWREVISION 和 OLDREVISION 组成。仅使用 Delta.java 类中定义的以下关系注释生成第一个 alter 语句:

public class Delta {

@EmbeddedId
private DeltaPK deltaPk;

@ManyToOne
@PrimaryKeyJoinColumns({
       @PrimaryKeyJoinColumn(name="appKey", referencedColumnName="appKey"),
       @PrimaryKeyJoinColumn(name="newRevision", referencedColumnName="revision")
})
private Revision newRevision;

@ManyToOne
@PrimaryKeyJoinColumns({
       @PrimaryKeyJoinColumn(name="appKey", referencedColumnName="appKey"),
       @PrimaryKeyJoinColumn(name="oldRevision", referencedColumnName="revision")
})
private Revision oldRevision;

每个 PrimaryKeyJoinColumn、'appKey'、'oldRevision' 和 'newRevision' 的名称值都是在 DeltaPK 类中定义的字段,而引用的ColumnName 值是在 Revision 类中定义的字段。

我尝试了很多变体,最接近的是当我注释掉 oldRevision 对象的“appKey”的 PrimaryKeyJoinColumn 时。然后生成第二个 alter 语句,但它只包含 oldRevision 值(不是 appKey),如您所料。任何关于如何实现这一点的想法或建议将不胜感激。

4

1 回答 1

0

在我发现如何解决这个问题之前,我不得不在调试器中浏览 EclipseLink 源代码一段时间。事实证明,我在最初的问题中没有提到问题的一个关键部分(因为我不知道这是问题的一部分)。Revision 类中的“appKey”和“revision”字段不是该表的主键,但是,它们确实构成了唯一性约束:

@Table(
    name = "REVISION",
    uniqueConstraints = @UniqueConstraint(columnNames = {"appKey", "revision"})
)

事实证明,EclipseLink 部分地基于此唯一性约束中 columnNames 的顺序来生成外键约束的名称。这导致我的两个外键约束都使用相同的名称生成,最终导致第二个约束被忽略并且没有生成。org.eclipse.persistence.tools.schemaframework.TableDefinition(如果您想将所有细节放在一起,请参阅以下方法。)

buildForeignKeyConstraint(List<String> fkFieldNames, List<String> pkFieldNames, TableDefinition targetTable, DatabasePlatform platform)
buildForeignKeyConstraintName(String tableName, String fieldName, int maximumNameLength, DatabasePlatform platform)
addForeignKeyConstraint(ForeignKeyConstraint foreignKey)

简而言之,当我像这样简单地重新排序 cloumnNames 的值时:

@UniqueConstraint(columnNames = {"revision", "appKey"})

我得到了两个不同命名的外键约束(因为 'revision' 和 'newRevision' 和 'oldRevision' 之间的两个映射),如下所示:

ALTER TABLE DELTA ADD CONSTRAINT DELTA_NEWREVISION FOREIGN KEY (NEWREVISION, APPKEY) REFERENCES REVISION (REVISION, APPKEY)
ALTER TABLE DELTA ADD CONSTRAINT DELTA_OLDREVISION FOREIGN KEY (OLDREVISION, APPKEY) REFERENCES REVISION (REVISION, APPKEY)

对于不同的数据库平台(我使用的是 Derby),您可能会得到略有不同的输出,但我认为一般问题和解决方案是相同的。我希望我解释得足够清楚,以便将来帮助其他人。

于 2013-07-26T23:13:51.997 回答