Question

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 login) {
    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:

alt text

keys from table1:

alt text

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

Was it helpful?

Solution

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

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top