hibernate automatically maps columns on the background. And after working with Grails a year now, I can assume that varying datatypes makes no difference to gorm— it can handle any non-primitive datatypes as its column without any much configuration. But see the given example mapping on Grails 2.4 using Hibernate 4:
class TableA {
String id
static hasMany = [joinTable: TableAJoinTableB]
static mapping = {
id generator: 'assigned'
}
}
class TableB {
BigInteger id
static hasMany = [joinTable: TableAJoinTableB]
static mapping = {
id generator: 'assigned'
}
}
class TableAJoinTableB {
String prop1
static belongsTo = [tablea: TableA, tableb: TableB]
static mapping = {
id composite: ["tablea", "tableb"]
}
}
Assuming that the data at hand respects this relationship, you perform a JOIN
query to the three tables using:
// Assuming the query below will *always* retrieve no more than 1 row.
TableAJoinTableB join = TableAJoinTableB.createCriteria().get {
tablea {
eq("id", "1KDSURT743")
}
eq("prop1", "AT")
}
And simply access the values from TableA
and TableB
using this:
println "id of TableA via join: " + join?.tablea?.id
println "id of TableB via join: " + join?.tableb?.id
But I can't get to make the second line work, instead it throws an error:
org.hibernate.TypeMismatchException
Provided
id
of the wrong type for classTableB
. Expected: classjava.math.BigInteger
, got classjava.lang.String
.
I could always change the id
of TableB
to String
just to end this argument. But there are times when I cannot do that:
e.g. the database primary key is REALLY a number thus will cause an "Invalid number" error when performing a query if I forced its id to String
How can I tell TableAJoinTableB
to join with TableB
using BigInteger
? Isn't Hibernate assume that they should connect using BigInteger
since its the datatype of the referencing table's id
. The connection to TableA
is already working and I can see that the connection to TableB
is not supposed to be that way different.
Using an overloaded setter methods for id
can be the answer. But it defeats the purpose of auto-mapping of Hibernate foreign keys. The simple solution that I discovered solved the problem:
TableAJoinTableB join = TableAJoinTableB.createCriteria().get {
tablea {
eq("id", "1KDSURT743")
}
eq("prop1", "AT")
}
println "id of TableA via join: " + join?.tablea?.id
// These won't work and causes the same error to be thrown.
// I'll try to investigate why:
// println "id of TableB via join: " + join?.getTableb()?.id
// println "id of TableB via join: " + join?.getTableb()?.get("id")
// println "id of TableB via join: " + join?.tableb?.id
// println "id of TableB via join: " + join?.tableb?.get("id")
// However, the following line works:
println "id of TableB via join: " + join?.getTableb().getId()