Prashant Verma
Prashant Verma

Reputation: 41

How to deep clone domain object in grails 3.3.11?

I'm trying to deep clone my domain object. It has around 10 one-to-one mapping and further they have more.

I tried the below snippet:

def deepClone() {
        def copy = this.class.newInstance()

        PersistentEntity entity = Holders.grailsApplication.mappingContext.getPersistentEntity(this.class.name)
        entity?.persistentProperties?.each { prop ->
            if (prop.isAssociation()) {
                if (prop.isOneToOne()) {
                    copy."${prop.name}" = this."${prop.name}"?.deepClone()
                } else if (prop.isOneToMany()) {
                    this."${prop.name}".each {
                        copy."addTo${StringUtils.capitalize(prop.name)}"(it?.deepClone())
                    }
                }
            } else if (prop.name != 'id') {
                if (this."${prop.name}" instanceof List) {
                    this."${prop.name}".each {
                        copy."addTo${StringUtils.capitalize(prop.name)}"(it)
                    }
                } else {
                    copy."${prop.name}" = this."${prop.name}"
                }
            }
        }

        return copy
    }

But prop.isAssociation is not found. Do anyone know how to check the association in grails 3.3.11. This used to work in 1.3.7 version.

Upvotes: 1

Views: 166

Answers (1)

Prashant Verma
Prashant Verma

Reputation: 41

I resolved this problem with reference from documentation Upgrading from Grails 3.2.x

Here is the new code snippet:

def deepClone() {

        def copy = this.class.newInstance()
        Holders.grailsApplication.mappingContext.getPersistentEntity(this.class.name)?.persistentProperties?.each { prop ->
            if (prop instanceof Association) {
                if (prop instanceof OneToOne) {
                    copy."${prop.name}" = this."${prop.name}"?.deepClone()
                } else if (prop instanceof OneToMany) {
                    this."${prop.name}".each {
                        copy."addTo${StringUtils.capitalize(prop.name)}"(it?.deepClone())
                    }
                }
            } else if (prop.name != 'id') {
                if (this."${prop.name}" instanceof List) {
                    this."${prop.name}".each {
                        copy."addTo${StringUtils.capitalize(prop.name)}"(it)
                    }
                } else {
                    copy."${prop.name}" = this."${prop.name}"
                }
            }
        }
        return copy
    }

As per the documentation:

The GrailsDomainClassProperty interface had many more methods to evaluate the type of the property such as isOneToOne, isOneToMany etc. and while PersistentProperty does not provide direct equivalents you can use instanceof as a replacement using one of the subclasses found in the org.grails.datastore.mapping.model.types package.

Upvotes: 2

Related Questions