GORM 域映射问题

GORM Domain Mapping Issue

我尝试实现的域模型有点复杂,但遇到了一些麻烦。 (最重要的是,我对这一切都很陌生!)

我有一个具有多个角色和多个测试的用户域。角色域效果很好。 Test 域稍微复杂一些,因为它需要两个外键,而不是像 Role 域中那样只需要 1 个。第一个外键是 user_id,第二个是 uni_id(大学 ID)。

用户域模型包含以下内容

class User {

    static hasMany = [roles:Role, tests:Test]

    Integer userId
    ...

    static mapping = {
        table 'user_data'
        id generator: 'assigned', name: 'userId', type: 'long'
        userId column: 'user_id'
        version false

        roles joinTable:[name:'user_role', key:'user_id']

        tests joinTable:[name:'user_test', key:'user_id'] // Here is where I run into trouble
    }

    static constraints = {
    }
}

测试域包含

class Test {

    static belongsTo = User
    static hasMany = [users:User]
    static hasOne = [uni:Uni]

    Integer testId // primary key
    String testType 

    static mapping = {
        table 'test'
        id generator: 'assigned', name: 'testId', type: 'long'
        testId column: 'test_id'
        users joinTable:[name:'user_test', key:'test_id']
        uni joinTable:[name:'user_test', key:'test_id'] // If I leave this out, everything is groovy
        version false
    }

    static constraints = {
    }
}

并且 Uni 域包含

class Uni {

    static belongsTo = Test
    static hasMany = [tests:Test]

    Integer uniId // primary key
    String shortName 
    String fullName 

    static mapping = {
        table 'uni'
        id generator: 'assigned', name: 'uniId', type: 'long'
        uniId column: 'uni_id'
        version false

        tests joinTable:[name:'user_test', key:'uni_id']
    }

    static constraints = {
    }
}

如果不清楚,我要做的是将大学 ID、测试 ID 和用户 ID 拉入 table user_test 以根据用户 ID 查找他们参加的考试。有没有简单的方法可以做到这一点?

我遇到的各种错误让我相信,出于某种原因,它正试图对 table test 而不是 user_test 执行所有操作。例如,

Unsuccessful: alter table test add uni_id int not null

我希望能够通过 user.tests.testTypeuser.tests.uni.fullName 或某种程度的方式访问与特定用户相对应的考试和大学信息。我究竟做错了什么?更重要的是,有没有更好的方法来做到这一点?!提前致谢!

编辑 1:我刚刚想到的一些有趣的事情..一个用户可以进行多次测试,但反之则不然。给定的测试永远不会在多人之间共享。所以我认为这会改变一些事情.. 我会做一些阅读,如果我想出任何新的东西,post。

编辑 2:这是角色域

class Role {

  static belongsTo = User
  static hasMany = [users:User]

  Integer roleId
  String shortName
  String roleName
  Integer roleLevel

  static mapping = {
    table 'role'
    id generator: 'assigned', name: 'roleId', type: 'long'
    roleId column: 'role_id'
    users joinTable:[name:'user_role', column:'user_id', key:'role_id']
    version false
  }

    static constraints = {
    }
}

编辑 3:我现在尝试将所有测试信息存储在测试域模型中,并简单地选择 Uni 名称作为测试中的一个字段存储,但是当我尝试这样做时出现奇怪的错误。我的新文件看起来像这样

class User {

    static hasMany = [roles:Role, tests:Test]

    Integer userId

    static mapping = {
        table 'user_data'
        id generator: 'assigned', name: 'userId', type: 'long'
        userId column: 'user_id'
        version false

        roles joinTable:[name:'user_role', key:'user_id']
    }

    static constraints = {
    }
}

class Test {

    static belongsTo = User

    Integer testId // primary key
    Integer testTypeId
    String testTypeName
    String testUni
    Date testDate

    static mapping = {
        table 'test'
        id generator: 'assigned', name: 'testId', type: 'long'
        testId column: 'test_id'
        version false
    }

    static constraints = {
    }
}

但现在当我尝试 运行 时出现以下错误 Caused by: org.hibernate.MappingException: Missing type or column for column[tests_test] on domain[User] referencing[Test]

知道那是什么意思吗?

好的,您遇到的一个问题是您正在尝试将用户与测试关联加入 table 与测试与单元关联。那是行不通的。

让我们从数据库的角度来看它。我不是 ASCII 艺术专家,所以我希望这张图不会让你的眼睛流血。

user_data (userId) |---|< (user_id) user_test (test_id) >|---| (testId) test

上图显示了用户域和测试域之间多对多关联的数据库实现类。您可以看到 user_data.userId 链接到 user_test.user_iduser_test.test_id 链接到 test.testId.

现在开始变得奇怪了。 Test 和 Uni 之间有两种不同的关联:双向一对一和一对多。我只是不明白。但我想说明一个关于你的加入 tables 的重要问题,所以就在这里。

test (testId) |---|< (test_id) user_test (uni_id) >|---| (uniId) uni

因为您正在为两个不同的关联使用相同的联接 table (user_test),所以您要求 GORM 创建一个 table,如下所示:

USER_TEST
- USER_ID
- TEST_ID
- UNIT_ID

GORM 不会这样做,因为连接 tables 应该只有两个字段。不仅如此,您还定义了数据库术语中的多对多,以及 GORM 术语中的双向一对一和一对多。哎哟!

待办事项

我建议的第一个更改是对 Test-Uni 关联使用不同的连接 table。

最终一切正常(在域模型方面进行了一些修改之后)

class User {

    static hasMany = [roles:Role, tests:Test]

    Integer userId

    static mapping = {
        table 'user_data'
        id generator: 'assigned', name: 'userId', type: 'long'
        userId column: 'user_id'
        version false

        roles joinTable:[name:'user_role', column:'role_id', key:'user_id']
    }

    static constraints = {
    }
}

class Test {

    User user
    Integer testId // primary key
    String testType
    String testUni
    Date testDate

    static mapping = {
        table 'test'
        id generator: 'assigned', name: 'testId', type: 'long'
        testId column: 'test_id'
        version false
    }

    static constraints = {
    }
}

class Uni {

    Integer uniId // primary key
    String shortName 
    String fullName 

    static mapping = {
        table 'uni'
        id generator: 'assigned', name: 'uniId', type: 'long'
        uniId column: 'uni_id'
        version false
    }

    static constraints = {
    }
}

现在我正在做的是从我的 GSP 的下拉选项卡中选择大学,并将其作为字符串 testUni 保存在测试中。然后,最大的变化是删除三者之间的所有 joinTables 并将 User user 添加到 Test。我仍然不太明白为什么我之前所做的不起作用,但我不会抱怨一个可用的应用程序!