我正在使用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