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

我有一个具有多个角色和多个测试的用户域。角色域效果很好。尽管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插入到表user_test中,以根据用户ID进行测试。有没有简单的方法可以做到这一点?

我遇到的各种错误使我相信,由于某种原因,它试图对表test而不是user_test执行所有操作。例如,
Unsuccessful: alter table test add uni_id int not null

我希望能够通过user.tests.testTypeuser.tests.uni.fullName或类似程度的内容访问与特定用户相对应的测试和大学信息。我究竟做错了什么?更重要的是,还有更好的方法吗?提前致谢!

编辑1:我刚刚想到的一些有趣的事情:一个用户可以进行多个测试,但事实并非如此。给定的测试永远不会在多个人之间共享。因此,我认为这会改变一些事情。如果我有新的想法,我会做一些阅读和发表。

编辑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:我现在试图将所有测试信息存储在Test域模型中,并只是选择Uni名称以存储为Test中的字段,但是当我尝试这样做时却遇到了奇怪的错误。我的新文件如下所示
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]时出现以下错误

知道那是什么意思吗?

最佳答案

好的,您遇到的一个问题是您试图与“测试到单元”关联共享“用户到测试”关联联接表。那是行不通的。

让我们用数据库术语来看一下。我不是ASCII艺术专家,所以我希望此图不会使您的眼睛流血。

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

上图显示了User和Test域类之间的多对多关联的数据库实现。您可以看到user_data.userId链接到user_test.user_id,而user_test.test_id链接到test.testId。

现在,这里开始变得怪异了。 Test和Uni之间有两种不同的关联:双向一对一和一对多。我只是不明白。但我想说明您的联接表的一个重要问题,就在这里。
test (testId) |---|< (test_id) user_test (uni_id) >|---| (uniId) uni

因为您将相同的联接表(user_test)用于两个不同的关联,所以您要求GORM创建如下表:
USER_TEST
- USER_ID
- TEST_ID
- UNIT_ID

GORM不会这样做,因为联接表应该只有两个字段。不仅如此,您还需要在数据库中定义多对多,而在GORM方面则定义双向一对一和一对多。哎哟!

去做

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

关于sql - GORM域映射问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32100922/

10-12 22:42