2013-07-23 44 views
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类中定义,并且referencedColumnName值是Revision类中定义的字段。

我已经尝试了一堆变体,而且我得到的最接近的是当我注释掉oldRevision对象的'appKey'的PrimaryKeyJoinColumn。然后生成第二个alter语句,但它只包含oldRevision值(不是appKey),就像您所期望的那样。任何想法或建议如何做到这一点将不胜感激。

+0

您是否尝试过使用joincolumn批注并使其可插入= false,updateable = false而不是PrimaryKeyJoinColumn批注? – Chris

+0

是的,我试过了,不幸的是我得到了同样的结果。 –

回答

0

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

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

原来,的EclipseLink正在生成的名字外键约束部分基于此唯一性约束中列名的排序。这导致我的外键约束被生成为具有相同的名称,最终导致第二个被忽略并且不被生成。 (见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"}) 

我两个不同命名的外键约束(因为“修订版”和“newRevison”和“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) 

你可能会得到slightl y不同的数据库平台的输出(我使用的是Derby),但我认为一般问题和解决方案是相同的。我希望我解释清楚,以便将来帮助别人。

相关问题