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
基本上它似乎做的是
- 如果 FK_ + table 名称 + _ + 列名大于限制(Oracle 为 30 个字符),则删除 FK_ 前缀。
- 如果仍然太长,请删除所有下划线或任何其他非字母或数字的内容。
- 如果还是太长,去掉元音
- 如果还是太长:
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 告诉我已经有一个同名的外键约束。
我在 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
基本上它似乎做的是
- 如果 FK_ + table 名称 + _ + 列名大于限制(Oracle 为 30 个字符),则删除 FK_ 前缀。
- 如果仍然太长,请删除所有下划线或任何其他非字母或数字的内容。
- 如果还是太长,去掉元音
- 如果还是太长:
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 告诉我已经有一个同名的外键约束。