views:

128

answers:

3

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

+1  A: 

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.

Yves M.
I already think of that but this isn't the problem. but columns have the property 'database default' which stand for 'Latin1_General' I check this on the column properties.
michel
comment on your edit: I noticed this. But why tries hibernate to reference to table.id instead of table1.login as stated in the annotation configuration 'referencedColumnName = "login"' ? If I change the primary key from table1 from 'id' to 'login' then the problem is not there. But unfortunately this isn't possible because table1.id must be the primary key of table1 and the manyToOne mapping from my application need to be set on table1.login from table2.table1_login
michel
Then you need to make table1.login your primary key or a unique column at least I'd say...
Yves M.
as I said: "But unfortunately this isn't possible because table1.id must be the primary key of table1 and the manyToOne mapping from my application need to be set on table1.login from table2.table1_login"And table1.login has already a unique key constraint. but this doesn't help.but thx anyway for your Help!
michel
A: 

Did you look what are the types of fields at database?

bahadir arslan
take a look at my edit from the startpost. thx
michel
I looked but i couldn't help; because i am not good at hibernate. I searched alot but i couldn't find right annotation. Sorry..
bahadir arslan
+1  A: 

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

Pascal Thivent
Thx for your suggestion but this possible solution doesn't work. still get the error: Column 'table1.id' is not the same data type as referencing column 'table2.table1_login' in foreign key 'FK1751F2B3CEB31922'Start a bounty now
michel
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. But if you say that this isn't possible then I must look for a other solution. Strange that this problem doesn't appear in Mysql btw
michel
No you are right then it doesn't make any sense that the FK constraint is there I wasn't aware of the fact that in MSSql a FK always must constraint another table's primary key. For it seems that this is not in MySQL InnoDB. Thx again for the explanation
michel
@michel I was partially wrong, a foreign key **can** also reference a `UNIQUE` column, not only the PK. I've updated my answer accordingly and provided the syntax to create the FK constraint on another column than the PK (but you need to make `login` unique, which makes sense anyway).
Pascal Thivent
login was always a unique key... that is the strange thing. I already notice the error when it isn't. then you get the message that the reference column isn't a candidate or primary key
michel
@Pascal Thivent see edit from original post. add image with constraints
michel
I can Alter table table2 after the DLL is done. But I was hoping that the hbm2dll can do this. And now I know he didn't I was wondering why hbm2dll doesn't do this.
michel
@michel I wonder if this would be accepted as an issue. Somehow, the whole hbm2ddL is screwed in your case (Hibernate can't possibly generate Table1 from the metadata, Hibernate is not aware of the real but non mapped PK). One could argue that the generated alter statement for the FK constraint is not correct but I don't know if this would be accepted given that the whole schema generation is broken here.
Pascal Thivent
not the solution but still the most information. bounty is yours. Thx again for your support
michel