我正在尝试实现一个复杂的域模型,但遇到了一些麻烦。 (最重要的是,我对这一切还是很陌生的!)
我有一个具有多个角色和多个测试的用户域。角色域效果很好。尽管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.testType
和user.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/