如何解决“ java.sql.SQLException:无法添加外键约束。”创建具有双重主/外键关系的表时

时间:2019-04-05 23:03:18

标签: mysql sql kotlin foreign-keys kotlin-exposed

我正在为使用Kotlin和Jetbrain的Exposed SQL库正在研究的项目建立数据库。并且我正在尝试在两个表cw_cache(父表)和cw_requests(子表)之间建立外键关系。

此设置可与Sqlite数据库一起正常使用,但是当我尝试在MySQL服务器数据库中创建表时不起作用。我收到错误信息“ java.sql.SQLException:无法添加外键约束。”

我已经在这里查看过类似的问题,并确保父表和子表中的列具有相同的数据类型,父表中的列实际上是键,并且在创建cw_cache表之前cw_requests表。

当我运行SHOW ENGINE INNODB STATUS;来查看外键错误时,会看到以下内容:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
2019-04-05 18:29:17 2e94 Error in foreign key constraint of table coursewatcher/cw_requests:
FOREIGN KEY (term) REFERENCES cw_cache(term) ON DELETE RESTRICT ON UPDATE RESTRICT):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Sqlite数据库中的

图: https://gyazo.com/220dd4b1a3d301419e0b8b73bfc80a68

相关代码:

cw_cache表:

object Cache : Table("cw_cache") {
    val crn = varchar("crn", 5).primaryKey()
    val term = varchar("term", 6).primaryKey()

    // other column initializers
}

cw_request表:

object Requests : Table("cw_requests") {
    val id = long("id").primaryKey()
    val orderId = long("order_id") references Orders.id
    val crn = varchar("crn", 5) references Cache.crn
    val term = varchar("term", 6) references Cache.term

    // other column initializers
}

1 个答案:

答案 0 :(得分:1)

根据此问题,目前尚未使用Exposed框架声明复合外键:https://github.com/JetBrains/Exposed/issues/511

对此问题的答复给出了手动解决方法的代码示例:

val t = TransactionManager.current()
val fk = ForeignKeyConstraint("fk_name",
                    t.identity(TableA), "{t.identity(TableA.idA)}, {t.identity(TableA.idA)}",
                    t.identity(TableB), "{t.identity(TableB.idA)}, {t.identity(TableB.idA)}",
                    ReferenceOption.RESTRICT,
                    ReferenceOption.RESTRICT)
t.exec(fk.createStatement().firsts())

我没有使用过Kotlin或Exposed框架,所以不要问我如何使用该代码示例。如果您觉得合适,请祝您好运。