Сохранение карт и списков свойств как JSON в Grails

РЕДАКТИРОВАТЬ: метод 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)

Для меня это не очень элегантное решение моей проблемы. Вопросы:

  1. Есть ли более простой подход для сохранения моих сложных динамических данных карты?
  2. Если мне нужно сделать это так, как сейчас, есть ли способ избежать взлома на шаге 3?
14
задан John Doppelmann 10 January 2012 в 10:42
поделиться