表1:

Field Type Null Key Default Extra
UserID int(11) NO PRI NULL auto_increment
Password varchar(20) NO
Username varchar(25) NO
Email varchar(60) NO

表2:

Field Type Null Key Default Extra
UserID int(11) NO MUL
PostID int(11) NO PRI NULL auto_increment
Title varchar(50) NO
Summary varchar(500) NO

错误:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: 无法添加或更新子行:外键约束失败 (myapp/table2,约束table2_ibfk_1外键(UserID)) 引用表1 (UserID))

我做错了什么?我读了http://www.w3schools.com/Sql/sql_foreignkey.asp,我不知道有什么问题。


当前回答

我花了一段时间才想明白。简单地说,引用另一个表的表中已经有数据,它的一个或多个值在父表中不存在。

如。 表2的数据如下:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

表1

UserID    Password    Username    Email
9         ********    JohnDoe     john@example.com

如果尝试ALTER table2并添加外键,则查询将失败,因为UserID=5在Table1中不存在。

其他回答

子表外键约束失败

这个问题可能是由以下原因引起的:

如果你在Spring mvc中这样做,你需要显式地描述id类型,因为有时mysql无法识别id的类型。所以你显式设置为在你的实体class@GeneratedValue(策略= GenerationType.IDENTITY)

也许当你添加userID列时,有一个特定表的数据,它已经建立,所以它将有一个默认值为0,尝试添加不带NOT NULL的列

一个简单的破解方法是在对表执行任何操作之前禁用外键检查。简单查询

SET FOREIGN_KEY_CHECKS=0

这将禁用与任何其他表的外键匹配。处理完表后,再次启用它

SET FOREIGN_KEY_CHECKS=1

这对我来说很管用。


请注意,当你这样做时,你进入了危险区。虽然确实存在有效的用例,但只有当您确定了解其含义时才应该这样做。

我也遇到过类似的问题。您正在尝试对一个有内容且列不可空的表应用外键。你有两个选择。

使要应用外键约束的列为可空。这样就可以应用外键,知道某些字段可以为空。(这就是我所做的。) 创建要应用外键约束的列,编写查询将外键插入该列,然后应用外键约束。(没有尝试过,但应该可以工作)

只是一点点修复: 使JoinColumn在Table1中为'nullable=true', 'UserID'字段在Table2中为'insertable=false'和'nullable=true'。

表1实体:

@OneToMany(targetEntity=Table2.class, cascade = CascadeType.ALL)
@JoinColumn(name = "UserID", referencedColumnName = "UserID", nullable = true)
private List<Table2> table2List;

表2实体:

@Column(insertable = false, nullable = true)
private int UserID;