1

I tried to serialize grails domains classes to Maps or similar in order to be able to store it in memcached.

I want to be able to read the objects only, I don't need gorm crud. Only to read them without breaking the kind of interfaces they have.

For instance: I could convert domains to maps, becouse it wouldn't break the interface for access like .<property> or .findall or similar

First I tried to do a manual serialization but it was very error prone. So I needed something more general.

Then I tried to serialize as a map with a grails codec.

Here is the testing repo.

Here is the snippet.

But I get StackOverFlowException.

I also tried to mark all the domains as Serializable but I need to reattach every domain when I bring them back from memcached to avoid hibernate errors like org.hibernate.LazyInitializationException: could not initialize proxy - no Session

Do you know a way to achieve this?

Is very frustrating to google search for something like this "storing domain classes in memcached" and find out is not a common problem.

user2427
  • 7,842
  • 19
  • 61
  • 71

3 Answers3

4

I haven't see an out-of-the-box solution for doing this, but if you wanted to keep it generic you could do it manually (and consistently) like this:

def yourDomainInst = DefaultGrailsDomainClass(YourDomainClazz)
List listOfOnlyPersistantProperties = yourDomainInst.persistantProperties

def yourNewMap

yourObjects.each { obj ->
   listOfOnlyPersistantProperties.each { prop ->
      def propName = prop.name
      yourNewMap.put(propName, obj."$propName")
   }
}

Something like that should work. Note there's probably a hundred errors because I can't try it out right now, but that is the general idea.

1

Have a look at: Retrieving a list of GORM persistent properties for a domain

Community
  • 1
  • 1
Chris
  • 8,031
  • 10
  • 41
  • 67
0

Domain or POGO (Plain Old Groovy Object) to Map

You can use YourDomain.gormPersistentEntity.persistentProperties to retrieve only the persistent properties on domains, for instance.

Read this answer on another thread for a more details on how to convert a domain or POGO object to Map.


Serialization

Using Grails' converters

grails.converters works most of the times. Currently there exists the XML and JSON converters:

def person = new Person(name: "Maicon", active: true) as grails.converters.JSON
assert person == '{"name":"Maicon","version":null,"active":false}'

You can use the setExcludes or setIncludes methods to filter the properties:

// person.includes = ['name'] // to include only name
// assert person.toString() == '{"name":"Maicon"}'

person.excludes = ['version', 'password']
assert person.toString() == '{"name":"Maicon","active":true}'

You have to have org.grails.plugins:converters as a dependency. If you have org.grails:grails-plugin-rest, then it's not needed.

Using JsonGenerator calling Options()

To customize ouput:

def generator = new JsonGenerator.Options()
    .excludeNulls()
    .excludeFieldsByName('version', 'password')
    .build()

def person = new Person(name: "John", active: true)
assert generator.toJson(person) == '{"name":"John","active":true}'

Read more here

Using JsonOuput

def json = JsonOutput.toJson(new Person(name: 'Max'))
assert json == '{"name":"Max","password":null,"active":false}'

Read more here


Avoiding org.hibernate.LazyInitializationException: could not initialize proxy - no Session

One way to avoid getting this error is to use the DTO (Data Transfer Object) pattern. This way domains are only used when persisting and retrieving data from the database. Although it might seem like unecessary repetition, decoupling from the interface and the database might save you some headache in the future .

Maicon Mauricio
  • 2,052
  • 1
  • 13
  • 29