我正在使用Grails 2.3.7中的父/子关系进行数据绑定,并且在删除时遇到问题。该表单有许多可选的子项,为了保持数据库的整洁,我想清除空白值(空值)。我发现了一些很好的文章,建议使用removeAll来过滤我的条目,但我无法删除或removeAll工作!Groovy removeAll闭合不会删除集合中的对象
例如......(家长有10个孩子,5个是空的)
def update(Parent parent) {
parent.children.getClass() // returns org.hibernate.collection.PersistentSet
parent.children.size() // returns 10
parent.children.findAll{ it.value == null }.size() // returns 5
parent.children.removeAll{ it.value == null } // returns TRUE
parent.children.size() // Still returns 10!!!
}
我读过PersistentSet是挑剔的equals()和hashCode()被手动实现,我已经做了在每个领域的类。让我感到困惑的是,removeAll如何返回true,表示Collection已经改变,但它没有改变。我已经坚持了几天,所以任何提示将不胜感激。谢谢。
更新:
我一直在尝试与孩子哈希码,这似乎是罪魁祸首。如果我根据id创建了一个基本的散列码(坏习惯),那么removeAll可以工作,但是如果包含该值,它将不再工作。例如...
// Sample 1: Works with removeAll
int hashCode() {
int hash1 = id.hashCode()
return hash1
}
// Sample 2: Doesn't work with removeAll
int hashCode() {
int hash1 = id.hashCode()
int hash2 = value == null ? 0 : value.hashCode()
return hash1 + hash2
}
// Sample Domain classes (thanks Burt)
class Parent {
static hasMany = [children: Child]
}
class Child {
String name
String value
static constraints = {
value nullable: true
}
}
此行为通过数据绑定步骤更新数据来解释,使其变脏。 (即:child.value.isDirty()== true)这是我的理解。
第一次Grails数据绑定获取父和孩子,并计算每个孩子的哈希码。接下来,应用数据更新使child.value变脏(如果变化),但Set的hashcode保持不变。当removeAll发现匹配时,它会使用脏数据构建一个hashCode,但是在Set中找不到该哈希码,因此无法删除它。基本上,removeAll只会在我的所有hashCode变量都干净时才起作用。
因此,如果数据必须干净才能删除它,一种解决方案是将其保存两次。像这样...
// Parent Controller
def update(Parent parent) {
parent.children.removeAll{ it.value == null } // Removes CLEAN children with no value
parent.save(flush:true)
parent.refresh() // parent.children is now clean
parent.children.removeAll{ it.value == null } // Removes (formerly dirty) children
parent.save(flush:true) // Success!
}
虽然这并不理想,但它可以工作。首先,我必须在数据库中允许空值,尽管它们只是短暂存在,我不想要它们。其次,做两次保存有点低效。当然必须有更好的方法?
你是怎么得到的,如果你打印孩子之前和之后removeAll出来? – injecteer 2014-09-29 16:15:24
请发布您的'''父'''类 – Victor 2014-09-29 16:17:37
您可以尝试:'parent.children.findAll {it.value == null} *。removeFromParent(parent)' – 2014-09-29 16:25:55