Problem adding @ManyToOne mapping on Non primary-key in SQL Server
I have a problem with changing my spring/hibernate application from MySql to SQL Server.
When Hibernate is updating the database by starting the server he want to creates(by hibernate.hbm2ddl.auto
set on update
) the database but a foreign-key fails on following error:
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'.
the mapping is as follows:
table1:
@Id
public String getLogin() {
return login;
}
public void setLogin(String log开发者_运维问答in) {
this.login = login;
}
table2:
@ManyToOne
@JoinColumn (name = "table1_login", referencedColumnName = "login", insertable=false, updatable=false)
public Table1 getTable1() {
return table1;
}
public void setTable1(Table1 table1) {
this.table1= table1;
}
++edit: SQL looks likes this:
keys from table1:
The table table1 is also used by an other application and therefore this table needs the column 'id' as primary key. So table1.id is primary key of table1. But this table1.id isn't used by hibernate, because hibernate use the table1.login as id (see annotations above). But why is SQL Server trying to set a foreign key to table1.id and not to table1.login ?
Thanks
Here is what the JPA specification writes about the Id
annotation:
9.1.8 Id Annotation
The Id annotation specifies the primary key property or field of an entity. The Id annotation may be applied in an entity or mapped superclass.
By default, the mapped column for the primary key of the entity is assumed to be the primary key of the primary table. If no
Column
annotation is specified, the primary key column name is assumed to be the name of the primary key property or field.
So I'm tempted to say that things behave as per the specification (and the login
property gets actually mapped on the id
column). Try to specify a Column
annotation:
@Id @Column(name = "login")
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
I can't recreated the table1 because this is an excisting table. I must use the alter table option from the DLL: "alter table table2 add constraint FK1751F2B3CEB31922 foreign key (table1_login) references table1" and I rather want the referential integrity.
To clarify, here is what Wikipedia says about foreign keys: the foreign key identifies a column or a set of columns in one (referencing) table that refers to a set of columns in another (referenced) table. The columns in the referencing table must be the primary key or other candidate key in the referenced table.
So, while you can't apply the above alter statement (table1_login
can't reference the id
of table1, you can make login
unique in table1 and create a FK constraint that would reference login
. Something like that:
ALTER TABLE table2
ADD CONSTRAINT FK_table2_table1
FOREIGN KEY (table1_login)
REFERENCES table1(login)
This assumes you added a UNIQUE
constraint on login in table1.
See also
- FOREIGN KEY Constraints
EDIT:
AFTER reading the message carefully I found this...
'table1.id' is not the same data type as referencing column 'table2.table1_login'
Table1.ID -> table2.table1_login.
ID and login are not the same datatype. So there is a wrong PK-FK relation around...
This sounds like you are using the wrong collation
. Both columns need the same collation. Otherwise you can not join them.
http://msdn.microsoft.com/en-us/library/aa174903(SQL.80).aspx
Make sure that you remove all explicitly set collations on the database creation script.
精彩评论