Grails / Groovy - Domain Object - Map of its Properties
Asked Answered
M

4

8

How can I get a map of the key/values of only the user-defined properties on one of my domain objects?

Problem is if I do this myself, I get my properties plus class, metaClass, constraints, closures, etc...

I assume Grails can do this fairly easily because it is done at some level in the scaffold code right? How can I do this myself?

Monagan answered 14/6, 2011 at 12:11 Comment(2)
Is this what you're after? https://mcmap.net/q/461018/-retrieving-a-list-of-gorm-persistent-properties-for-a-domainStowe
That's exactly what I was going to suggest. You have to be careful with transient properties obviously.Hertel
H
10

Try this

class Person{
    String name
    String address
}

def filtered = ['class', 'active', 'metaClass']

def alex = new Person(name:'alex', address:'my home')

def props = alex.properties.collect{it}.findAll{!filtered.contains(it.key)}

props.each{
    println it
}

It also works if you use alex.metaClass.surname = 'such'. This property will be displayed in the each loop

Hopkins answered 15/6, 2011 at 11:19 Comment(1)
This works for normal groovy classes, but is not so neat for grails domain objects as grails domain objects have extra magic wrapped around them that will get printed as well.Flashback
D
3

This is an old question, but I just ran across this requirement and found another solution that is worth answering here for others who come across this thread. I have put together an example based on that thread:

Sample Bean

class SampleBean {

    long id
    private String firstName
    String lastName
    def email

    Map asMap() {
        this.class.declaredFields.findAll { !it.synthetic }.collectEntries {
            [ (it.name):this."$it.name" ]
        }
    }
}

Test Class

class Test {

    static main(args) {
        // test bean properties
        SampleBean sb = new SampleBean(1,'john','doe','[email protected]')

        println sb.asMap()
    }

}

The SampleBean I put a variety of fields to show that it works, this is the output of the println:

[id:1, firstName:john, lastName:doe, email:[email protected]]
Dolmen answered 17/9, 2015 at 20:47 Comment(1)
This works for normal groovy classes, but is not so neat for grails domain objects as grails domain objects have extra magic wrapped around them that will get printed as well.Flashback
C
0

I think the best way is to use .properties on a domain object to get map of the fields in grails , tested in grails 2.1

class Person{
String firstName
String lastName

} 
def person=new Person()
person.firstName="spider"
person.lastName="man"
def personMap=person.properties 
Crying answered 13/11, 2018 at 10:2 Comment(1)
The question asks about only returning user-defined properties - person.properties will return more than just the user-defined properties.Nic
C
0

Grails Domain Objects

You can use Grails Gorm's getPersistentProperties(), if you are not including any transient properties on your map.

def domainProperties = [:]

YourDomain.gormPersistentEntity.persistentProperties.each { prop ->
    domainProperties.put(prop.name, yourDomainObject."$prop.name")
}

If you want to include transient properties, just write another loop on the property transients:

YourDomain.transients.each { propName ->
    domainProperties.put(propName, yourDomainObject."$propName")
}

Read my answer here for some more detail on persistentProperties.


Groovy Objects

For simple POGOs, as others pointed out in their answers, the following does the job:

def excludes = ['class']
def domainProperties = yourPogo.properties.findAll { it.key !in excludes }

or

Map map = [:]
yourPogo.class.declaredFields.each {
   if (!it.synthetic) map.put(it.name, yourPogo."$it.name")
}

You can get the best alternative that suits your needs and implement it on a method in a trait to be inherited or create a utility method that accepts the object as argument.

Cathexis answered 10/3, 2023 at 19:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.