EDIT: метод onload () изменен на afterLoad (): в противном случае объекты могут быть неправильно переданы на карту.
В настоящее время я использую некоторые классы домена с большим количеством динамических и сложных свойств., что мне нужно постоянно сохранять и обновлять.
Я храню их в структуре Map для каждого класса, поскольку это облегчает ссылки на них в моих контроллерах и т. д.
Однако, поскольку Grails не делаетпохоже, что в БД можно сохранять сложные типы свойств, такие как List и Map. Я использую следующий подход для достижения этого с помощью объектов JSON String:
class ClassWithComplexProperties {
Map complexMapStructure //not persisted
String complexMapStructureAsJSON //updated and synched with map via onload,beforeInsert,beforeUpdate
static transients = ['complexMapStructure']
def afterLoad() { //was previously (wrong!): def onLoad() {
complexMapStructure=JSON.parse(complexMapStructureAsJSON)
}
def beforeInsert() {
complexMapStructureAsJSON= complexMapStructure as JSON
}
def beforeUpdate() {
complexMapStructureAsJSON= complexMapStructure as JSON
}
static constraints = {
complexMapStructureAsJSON( maxSize:20000)
}
}
Это работает хорошо, пока я загружаю данные только изБД, но у меня возникают проблемы, когда я хочу сохранить свои изменения в БД.Например, когда я делаю следующее
/* 1. Load the json String, e.g. complexMapStructureAsJSON="""{
data1:[[1,2],[3,4]],//A complex structure of nested integer lists
data1:[[5,6]] //Another one
}""" :
*/
ClassWithComplexProperties c=ClassWithComplexProperties.get(1)
// 2. Change a value deep in the map:
c.complexMapStructure.data1[0][0]=7
// 3. Try to save:
c.save(flush:true)
Это обычно не будет работать, так как, я думаю (?), GORM будет игнорировать запрос save () из-за того, что сама карта является временной, и нетизменения найдены в постоянных свойствах.
Я могу заставить его работать так, как задумано, если взломаю шаг 3 выше и изменить его на:
// 3.Alternative save:
complexMapStructureAsJSON="" //creating a change in persisted property (which will be overwritten anyway by the beforeUpdate closure)
c.save(flush:true)
Для меня это не очень элегантное решение моей проблемы.Вопросы:
- Существует ли более простой подход для сохранения моих сложных динамических картографических данных?
- Если мне нужно сделать это так, как я делаю в настоящее время, есть ли способ избежать взлома на шаге 3?