EclipseLink 如何命名外键?

How does EclipseLink name foreign keys?

我在 Java 项目中使用 EclipseLink 2.6.2 和 Oracle。我想了解 EclipseLink 如何决定命名外键。

目前,当我启动我的应用程序时,出现约束名称已存在的错误。我可以查询数据库并查看创建的外键是什么,我看到了具有相同名称的外键,但我不清楚它是如何创建名称的。它显然去掉了任何元音,但它是使用 table 一个和 table 两个,还是列名?

这是错误:

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-02264: name already used by an existing constraint
Error Code: 2264
Call: ALTER TABLE publctncompntdef_hist_ref ADD CONSTRAINT pblctncmpntdfbdpckCmpnntDfntnd FOREIGN KEY (bidpackComponentDefinitionId) REFERENCES bidpckcompntdef (bidpackComponentDefinitionId)

它试图创建的外键名称是:pblctncmpntdfbdpckCmpnntDfntnd

它正在尝试为 table publctncompntdef_hist_ref 到 table 创建外键 bidpackComponentDefinitionId 引用 table bidpckcompntdef 和列 bidpackComponentDefinitionId

但是它已经为 table publctncompntdefref 创建了一个同名的外键,列 bidpackComponentDefinitionId 到 table bidpckcompntdef 和列 bidpackComponentDefinitionId

我用谷歌搜索等等,但似乎找不到关于外键命名策略的文档。

此外,这是@JoinTable 值:

@JoinTable(name = "publctncompntdef_hist_ref",
           joinColumns={@JoinColumn(name="publicationHistoryId",referencedColumnName="id")},
           inverseJoinColumns={@JoinColumn(name="bidpackComponentDefinitionId",referencedColumnName="bidpackComponentDefinitionId")})

@JoinTable(name = "publctncompntdefref",
        joinColumns={@JoinColumn(name="bidpackComponentDefinitionId",referencedColumnName="bidpackComponentDefinitionId")},
        inverseJoinColumns={@JoinColumn(name="publicationId",referencedColumnName="id")})

我想我明白了。我最初并没有意识到 EclipseLink 是开源的,但我终于发现了这一点并从以下位置下载了代码:https://github.com/eclipse/eclipselink.runtime

基本上它似乎做的是

  1. 如果 FK_ + table 名称 + _ + 列名大于限制(Oracle 为 30 个字符),则删除 FK_ 前缀。
  2. 如果仍然太长,请删除所有下划线或任何其他非字母或数字的内容。
  3. 如果还是太长,去掉元音
  4. 如果还是太长:
    4a.检查没有元音的列名是否大于限制(30 个字符)。如果是这样,使外键名称只是列名减去元音,从末尾截断为最大大小
    4b.否则,将 table 名称截断为剩余的字符数(最大限制 - 列名称长度)

我的情况是这样的:
Table 名称 = publctncompntdefref(19 个字符)和列名称 = bidpackcomponentdefinitionid(28 个字符)
减去元音 = pblctncmpntdfrf (15chars) 和 bdpckcmpnntdfntnd (17chars)
连接这两个给我们 32 个字符。由于没有元音的列名少于 30 个字符(oracle 的最大值),将 table 名称截断为(30-17 = 13 个字符),即 pblctncmpntdf。整个外键名称是 pblctncmpntdfbdpckcmpnntdfntnd.

类似地,当我有 table name = publctncompntdef_hist_ref 和 column name = bidpackcomponentdefinitionid,没有元音时,我得到了 pblctncmpntdfhstrf 和 bdpckcmpnntdfntnd。 table 名称为 18 个字符,列名为 17 个字符。因此table需要截断为13个字符,所以pblctncmpntdfhstrf变成了pblctncmpntdf,整个外键变成了pblctncmpntdfbdpckcmpnntdfntnd.

这解释了为什么 EclipseLink 告诉我已经有一个同名的外键约束。