mysql - 创建具有双主外键关系的表时如何修复 "java.sql.SQLException: Cannot add foreign key constraint."

标签 mysql sql kotlin foreign-keys kotlin-exposed

我正在使用 Kotlin 和 Jetbrain 的公开 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_请求表:

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
}

最佳答案

根据此问题,声明复合外键当前未通过 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 框架,所以不要问我如何使用该代码示例。如果它对您有意义,祝您好运。

关于mysql - 创建具有双主外键关系的表时如何修复 "java.sql.SQLException: Cannot add foreign key constraint.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55544341/

相关文章:

mysql string group_concat 给我一个错误

java - 找不到合适的驱动程序 Postgres JDBC

mysql - 为什么 DriverManager.getConnection() 查找在 GroovyConsole 中失败?

mysql - 使用与另一个表的匹配仅从一个表中选择数据

mysql - MIN 和 MAX 字符串

sql - 通过SQL查询查找字符串中相同字符的每个位置

java - Fragment 无法从 ViewModel 获取值

android - 如何在 Kotlin 数据类中使用带空格的变量

kotlin - 使用 Quarkus/Kotlin 上传多部分文件

php - WordPress 在数据库中查找和替换