¿Cómo puedo duplicar un objeto de dominio en Grails?
grails-2.0 grails-domain-class (2)
No hay. Se ha solicitado http://jira.grails.org/browse/GRAILS-3532 . Alguien ha agregado un código a ese problema que podría ser útil para usted.
Quiero hacer una copia de un objeto de dominio. ¿Cuál es la forma más simple de lograr esto?
Me di cuenta de que podía crear un nuevo registro y luego iterar sobre cada uno de los campos copiando los datos campo por campo, pero pensé que debía haber una manera más fácil de hacerlo ...
En Rails hay una forma simple de hacer esto:
#rails < 3.1
new_record = old_record.clone
#rails >= 3.1
new_record = old_record.dup
¿Hay algún equivalente en Grails?
He adaptado un fragmento de código que hace la clonación profunda de las clases de dominio. He estado usando mi sistema y funciona muy bien (en la mayoría de los casos). El código a continuación es una adaptación que se encuentra en http://grails.1312388.n4.nabble.com/Fwd-How-to-copy-properties-of-a-domain-class-td3436759.html
En mi aplicación, el usuario tiene la opción de guardar como algunos tipos de objetos y yo uso el deepClone para hacer eso.
Puede especificar propiedades "no clonables". Para eso, necesita especificar un mapa estático (en su clase) con las propiedades que no desea clonar, por ejemplo:
static notCloneable = [''quoteFlows'',''services'']
static hasMany = [quotePacks: QuotePack, services: Service, clients: Client, quoteFlows: QuoteFlow]
static Object deepClone(domainInstanceToClone) {
//TODO: PRECISA ENTENDER ISSO! MB-249 no youtrack
//Algumas classes chegam aqui com nome da classe + _$$_javassist_XX
if (domainInstanceToClone.getClass().name.contains("_javassist"))
return null
//Our target instance for the instance we want to clone
// recursion
def newDomainInstance = domainInstanceToClone.getClass().newInstance()
//Returns a DefaultGrailsDomainClass (as interface GrailsDomainClass) for inspecting properties
GrailsClass domainClass = domainInstanceToClone.domainClass.grailsApplication.getDomainClass(newDomainInstance.getClass().name)
def notCloneable = domainClass.getPropertyValue("notCloneable")
for(DefaultGrailsDomainClassProperty prop in domainClass?.getPersistentProperties()) {
if (notCloneable && prop.name in notCloneable)
continue
if (prop.association) {
if (prop.owningSide) {
//we have to deep clone owned associations
if (prop.oneToOne) {
def newAssociationInstance = deepClone(domainInstanceToClone?."${prop.name}")
newDomainInstance."${prop.name}" = newAssociationInstance
} else {
domainInstanceToClone."${prop.name}".each { associationInstance ->
def newAssociationInstance = deepClone(associationInstance)
if (newAssociationInstance)
newDomainInstance."addTo${prop.name.capitalize()}"(newAssociationInstance)
}
}
} else {
if (!prop.bidirectional) {
//If the association isn''t owned or the owner, then we can just do a shallow copy of the reference.
newDomainInstance."${prop.name}" = domainInstanceToClone."${prop.name}"
}
// @@JR
// Yes bidirectional and not owning. E.g. clone Report, belongsTo Organisation which hasMany
// manyToOne. Just add to the owning objects collection.
else {
//println "${prop.owningSide} - ${prop.name} - ${prop.oneToMany}"
//return
if (prop.manyToOne) {
newDomainInstance."${prop.name}" = domainInstanceToClone."${prop.name}"
def owningInstance = domainInstanceToClone."${prop.name}"
// Need to find the collection.
String otherSide = prop.otherSide.name.capitalize()
//println otherSide
//owningInstance."addTo${otherSide}"(newDomainInstance)
}
else if (prop.manyToMany) {
//newDomainInstance."${prop.name}" = [] as Set
domainInstanceToClone."${prop.name}".each {
//newDomainInstance."${prop.name}".add(it)
}
}
else if (prop.oneToMany) {
domainInstanceToClone."${prop.name}".each { associationInstance ->
def newAssociationInstance = deepClone(associationInstance)
newDomainInstance."addTo${prop.name.capitalize()}"(newAssociationInstance)
}
}
}
}
} else {
//If the property isn''t an association then simply copy the value
newDomainInstance."${prop.name}" = domainInstanceToClone."${prop.name}"
if (prop.name == "dateCreated" || prop.name == "lastUpdated") {
newDomainInstance."${prop.name}" = null
}
}
}
return newDomainInstance
}