在 Hibernate 中将两个表与 BigInteger 数据类型关联时出错

Error when relating two tables with BigInteger datatype in 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 ——它可以处理任何非原始数据类型作为它的列而无需任何配置。但是请参阅使用 Hibernate 4 在 Grails 2.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"]
    }
}

假设手头的数据尊重这种关系,您使用以下方法对三个 table 执行 JOIN 查询:

// Assuming the query below will *always* retrieve no more than 1 row.
TableAJoinTableB join = TableAJoinTableB.createCriteria().get {
    tablea {
        eq("id", "1KDSURT743")
    }
    eq("prop1", "AT")
}

并使用以下方法简单地访问 TableATableB 中的值:

println "id of TableA via join: " + join?.tablea?.id
println "id of TableB via join: " + join?.tableb?.id

但是我无法使第二行工作,而是抛出一个错误:

org.hibernate.TypeMismatchException

Provided id of the wrong type for class TableB. Expected: class java.math.BigInteger, got class java.lang.String.

我总是可以将 TableBid 更改为 String 来结束这场争论。但有时我做不到:

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

如何告诉 TableAJoinTableB 使用 BigInteger 加入 TableB? Hibernate 是否假设他们应该使用 BigInteger 进行连接,因为它是引用 table 的 id 的数据类型。与 TableA 的连接已经正常工作,我可以看到与 TableB 的连接不应该有那样的不同。

id 使用重载的 setter 方法可能是答案。但它违背了 Hibernate 外键 auto-mapping 的目的。我发现的简单解决方案解决了问题:

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()