有一种情况,域本身就是一个属性,如下所示:
Group{
String name
Role role
static belongsTo=[boss:Group]
static hasMany=[children:Group,supporters:Group]
}
static constraint={
boss nullable:true
supporters validator: {supporters, group->
supporters?.each {Group supplier ->
if(!(supporters.role == Role.OPS)){
return "domain.not.supporters.object"
}
}
return true
}
}
}
Role{
MANAGER,LEADER,DEVELOPERS,OPS
}
以上支持者具有 OPS 角色,我们也为其添加了验证。总体支持者不属于原始的经理>领导者>开发人员层次结构
。
现在,当我创建几个子组对象时,会说 MANAGER_RAD > LEAD_BAD ->( DEV_JACK 和 DEV_MOHAN)
并且支持者仅提供给经理。下面的代码将帮助您理解该场景:
Group manager = new Group(name:'MANAGER_RAD')
manager.addToSupporters(new Group(name:'OPS_BISK').save(flush:true))
manager.addToSupporters(new Group(name:'OPS_BAHADUR').save(flush:true))
Group lead = new Group(name:'LEAD_BAD').save(flush:true)
lead.addToChildren(new Group(name:'DEV_JACK').save(flush:true))
lead.addToChildren(new Group(name:'DEV_MOHAN').save(flush:true))
lead.save(flush:true)
manager.addToChildren(lead)
manager.save()
现在,当我们尝试按如下方式获取经理的子级时(例如在我们的 Bootstrap 中):
Group manager = Group.findByName('MANAGER_RAD')
println "------Manager team members---->$manager.children"
println "------supporters for Manager---->$manager.supporters"
预期输出是:
------Manager team members---->[LEAD_BAD(id:2)]
------supporters for Manager---->[OPS_BAHADUR(id:7),OPS_BISK(id:7)]
但是返回的输出是:
------Manager team members---->[LEAD_BAD(id:2),OPS_BAHADUR(id:7),OPS_BISK(id:7)]
------supporters for Manager---->[LEAD_BAD(id:2),OPS_BAHADUR(id:7),OPS_BISK(id:7)]
如何获得预期的输出。
任何帮助都是值得的。
最佳答案
由于您的代码具有自引用属性(boss)以及同一类型的两个不同关联属性,因此 Grails 无法创建正确的架构。
来自 Grails 文档:
Occasionally you may find yourself with domain classes that have multiple properties of the same type. They may even be self-referential, i.e. the association property has the same type as the domain class it's in. Such situations can cause problems because Grails may guess incorrectly the type of the association.
在您的情况下,Grails 正在生成一个表,并且您的 child 和支持者属性将绑定(bind)到架构中的 boss_id 列。
要克服这种情况,您可以使用 mappedBy 并指定要绑定(bind)到属性名称的子属性和支持者属性的属性名称。
更改后,您的域类将如下所示:
class Group {
String name
Role role
static belongsTo = [boss: Group]
static hasMany = [children: Group, supporters: Group]
static mapping = {
table 'groups'
}
static mappedBy = [children : "none",
supporters: "none"]
static constraints = {
boss nullable: true
role nullable: true
supporters validator: { supporters, group ->
supporters?.each { Group supplier ->
if (supporters.role != Role.OPS) {
return "domain.not.supporters.object"
}
}
return true
}
}
}
enum Role {
MANAGER, LEADER, DEVELOPERS, OPS
}
现在 Grails 将为您生成两个表:groups 和 groups_groups。 如果您跳过任一属性的 mappedBy,该属性将绑定(bind)到 groups 表中的“boss_id”列。
groups_groups 表的结构为:
+-------------------+----------+---------------------+
| group_children_id | group_id | group_supporters_id |
+-------------------+----------+---------------------+
引用https://grails.github.io/grails-doc/latest/guide/GORM.html#domainClasses以获得更多解释。
关于java - grails域类多重循环引用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31871081/