2013-07-12 8 views
7

Ich möchte eine Kopie eines Domain-Objekts erstellen. Was ist der einfachste Weg, dies zu erreichen?Wie kann ich ein Domänenobjekt in Grails duplizieren?

Ich weiß, ich könnte einen neuen Datensatz erstellen, und dann das Datenfeld-für-Feld Kopieren jedes der Felder durchlaufen - aber ich dachte, es muss ein einfacher Weg, dies zu tun ...

In Schienen gibt es eine einfache Möglichkeit, dies zu tun:

Gibt es eine Entsprechung in Grails?

Antwort

7

Ich habe ein Stück Code angepasst, die den tiefen Klon von Domain-Klassen machen. Ich habe in meinem System verwendet und es funktioniert sehr gut (in den meisten Fällen). Der Code unten ist eine Anpassung gefunden in http://grails.1312388.n4.nabble.com/Fwd-How-to-copy-properties-of-a-domain-class-td3436759.html

In meiner Anwendung hat der Benutzer die Option zu speichern als einige Art von Objekten, und ich benutze die DeepClone, um das zu tun.

Sie können "nicht klonbare" Eigenschaften angeben. Dafür benötigen Sie eine statische Karte angeben (in der Klasse) mit den Eigenschaften, die Sie zum Beispiel nicht klonen möchten:

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 
} 
+0

vor Rücksendung der Sache habe ich versucht, es zu retten, aber es null angezeigt wird. ..wie kann dieses neue Objekt speichern – roanjain

+0

Hallo @roanjain, ich werde diesen Code überprüfen, um zu überprüfen, ob es aktualisiert wird. aber ich kann sagen, dass ich es erfolgreich verwende, um mehrere Klassen zu klonen. – cantoni

Verwandte Themen