简体   繁体   中英

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM