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

时间:2016-01-15 14:17:44

标签: hibernate grails gorm

会自动在背景上映射列。在使用Grails一年后,我可以假设不同的数据类型与没有区别 - 它可以处理任何非原始数据类型作为其列而没有任何多少配置。但是请参阅使用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"]
    }
}

假设手头的数据尊重这种关系,你可以使用以下方法对这三个表执行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

     

为类id提供了错误类型的TableB。预期:课程java.math.BigInteger,获得课程java.lang.String

我总是可以将id的{​​{1}}改为TableB,只是为了结束这个论点。但有时候我不能这样做:

  

e.g。数据库主键实际上是一个数字因此在执行查询时会导致“无效数字”错误,如果我将其ID强制为String

如何使用String告诉TableAJoinTableB加入TableB?不是Hibernate假定它们应该使用BigInteger连接,因为它是引用表的BigInteger的数据类型。与id的连接已经起作用,我可以看到与TableA的连接不应该那么不同。

1 个答案:

答案 0 :(得分:0)

使用id的重载setter方法可以解答。但它违背了自动映射Hibernate外键的目的。我发现的简单解决方案解决了这个问题:

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