将spring / hibernate应用程序从MySql更改为SQL Server时出现问题。
当Hibernate通过启动他想要创建的服务器(通过hibernate.hbm2ddl.auto
在update
上设置)数据库来更新数据库时,但是外键在出现以下错误时失败:
Unsuccessful: alter table table2 add constraint FKDC2DC97ECEB31922 foreign key (login) references table1
Column 'table1.id' is not the same data type as referencing column 'table2.table1_login' in foreign key 'FKDC2DC97ECEB31922'.
映射如下:
表1:
@Id
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
表2:
@ManyToOne
@JoinColumn (name = "table1_login", referencedColumnName = "login", insertable=false, updatable=false)
public Table1 getTable1() {
return table1;
}
public void setTable1(Table1 table1) {
this.table1= table1;
}
++编辑: SQL看起来像这样:
来自table1的
键:
表table1也被其他应用程序使用,因此该表需要列'id'作为主键。所以table1.id是table1的主键。但是这个table1.id不是由hibernate使用的,因为hibernate使用table1.login作为id(参见上面的注释)。但是为什么SQL Server尝试将外键设置为table1.id而不是table1.login?
由于
答案 0 :(得分:1)
修改强>
仔细阅读邮件后我发现了......
'table1.id'与引用列'table2.table1_login'
的数据类型不同表1. ID - >表2。的 table1_login 强>
ID和登录的数据类型不同。所以PK-FK关系错误......
这听起来好像你使用了错误的collation
。两列都需要相同的排序规则。否则你不能加入他们。
http://msdn.microsoft.com/en-us/library/aa174903(SQL.80).aspx
确保在数据库创建脚本中删除所有显式设置的排序规则。
答案 1 :(得分:1)
以下是JPA规范关于Id
注释的内容:
9.1.8 Id注释
Id注释指定了 主键属性或字段 实体。 Id注释可能是 应用于实体或映射 超类。
默认情况下,映射列为 假定实体的主键 成为主要的主键 表。如果没有
Column
注释 指定,主键列名称 假设是。的名称 主键属性或字段。
所以我很想说事情符合规范(login
属性实际映射到id
列)。尝试指定Column
注释:
@Id @Column(name = "login")
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
我无法重新创建table1,因为这是一个表格。我必须使用DLL中的alter table选项:“alter table table2 add constraint FK1751F2B3CEB31922 foreign key(table1_login)reference table1”,我更喜欢参照完整性。
为了澄清,以下是维基百科关于外键的说法:外键在一个(引用)表中标识一列或一组列,引用另一个(引用)表中的一组列。引用表中的列必须是引用表中的主键或其他候选键。
因此,虽然您无法应用上述alter语句(table1_login
无法引用table1的id
,但您可以login
唯一在table1中创建一个引用login
的FK约束。类似的东西:
ALTER TABLE table2
ADD CONSTRAINT FK_table2_table1
FOREIGN KEY (table1_login)
REFERENCES table1(login)
这假设您在table1中的登录时添加了UNIQUE
约束。