我有一个复杂的域模型,我试图实施,但我遇到了一些麻烦。 (最重要的是,我对这一切都很陌生!)
我有一个具有多个角色和多个测试的用户域。角色域工作得很好。 Test域有点复杂,因为它需要两个外键而不是像Role域中那样只有一个。第一个外键是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]
知道那是什么意思吗?
答案 0 :(得分:1)
好的,您遇到的一个问题是您尝试与Test-to-Unit关联共享User-to-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关联使用不同的连接表。
答案 1 :(得分:0)
最后让一切正常(在对域模型进行了一些修改之后)
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保存在Test中。然后,最大的变化是删除三者之间的所有joinTables并将User user
添加到Test。我仍然有点模糊为什么我之前做的事情没有工作,但我不会抱怨工作的应用程序!