0

I am trying to save a generic JSONObject to a Domain object using Grail's MongoDB plugin. Basically it doesn't work with regular properties (not surprising). So I added a dynamic property which saves the JSONObject to the DB and pulls it back out (yay). However, since I've replaced the default JSON serializer (due to bad behavior with MongoDB Plugin and Domain objects) with Jackson serializer the dynamic property is not being serialized.

What API can I use to get all dynamic properties added to a Domain to serialize it? Object.properties() doesn't return it. I can't find any other method to return it. I have to modify Jackson to serialize Grails objects now. Any ideas how that might be easiest?

Here is my object:

class ProblemAttempt {

   static final STEP_GUIDED = 'guided'
   static final STEP_INDEPENDENT = 'independent'

   static constraints = {
       timeSpent nullable: true
   }

   static mapWith="mongo"

   static mapping = {
       lessonAttemptId index: true
   }

   static embedded = ['tags']

   ObjectId id
   ObjectId problemId
   ObjectId userId
   String lessonExternalId
   ObjectId lessonAttemptId
   Date timeAnswered
   String stepName
   Boolean correct
   Integer timeSpent
   String lessonStatus
   List<String> tags

   ProblemAttempt(User user, String lessonExternalId, LessonAttempt attempt, String stepName, ObjectId problemId, boolean correct, Object answer) {

      this.userId = user.id
      this.lessonExternalId = lessonExternalId
      this.correct = correct
      this.lessonAttemptId = attempt.id
      this.lessonStatus = LearningStatus.INCOMPLETE
      this.problemId = problemId
      this.stepName = stepName
      this.timeAnswered = new Date()
      this['answer'] = answer  // have to use dynamic properties to persist generic JSON objects

      tags = []
      user.aspects.each {ProfileAspect aspect ->
          tags << aspect.class.simpleName
      }

      user.groups.each {DomainReference group ->
          tags << group.name
      }
  }

  public Object getUserAnswered() {
      return this['answer'] // this was added to handle serializing into json
  }

}
chubbsondubs
  • 37,646
  • 24
  • 106
  • 138
  • 1
    Can you add an example what you have right now for domain object (the dynamic properties)? – dmahapatro Mar 01 '14 at 04:33
  • I added the object, and you can see the dynamic properties as well as my solution which is to add a different getter that will be used by the serializer to send the object to the client. However, this getter won't be saved to the DB because MongoDB ignores it since it isn't embedded. – chubbsondubs Mar 03 '14 at 16:07
  • The problem with this solution is I can't seem to use dynamic properties within unit tests. I've tried to migrate to Integration Test but those fail too. So I'd still be interested in finding a solution that doesn't use dynamic properties. – chubbsondubs Mar 04 '14 at 03:48

1 Answers1

0

Usually a fixed property of type Map or List (depending on the nature of your JSON) should be fine here. Simply make sure you are saving the java collections, rather than Jackson-objects. The latter can not be BSON-serialized 1 to 1

injecteer
  • 20,038
  • 4
  • 45
  • 89
  • 1
    In the past when I try to do things like that MongoDB can't handle collections within collections. So List> will not work. It'll save List, with nothing in it or List with empty Maps. It's because of MongoDB plugin's bad design wrt to handling polymorphism and typing. – chubbsondubs Mar 01 '14 at 02:41