다음은 딥 (deep) 복제 버전입니다. 특정 요구를 충족시키기 위해 약간 사용자 정의되었지만 매우 일반적입니다. 그리고 저는이 시나리오가 시나리오에 잘 설명되어 있다고 확신합니다.
Object deepClone(def domainInstanceToClone, def notCloneable) {
return deepClone(domainInstanceToClone, notCloneable, null)
}
Object deepClone(def domainInstanceToClone) {
return deepClone(domainInstanceToClone, null, null)
}
Object deepClone(def domainInstanceToClone, def notCloneable, def bindOriginal) {
if (domainInstanceToClone.getClass().name.contains("_javassist"))
return null
//Our target instance for the instance we want to clone
def newDomainInstance = domainInstanceToClone?.getClass()?.newInstance()
//Returns a DefaultGrailsDomainClass (as interface GrailsDomainClass) for inspecting properties
GrailsClass domainClass = domainInstanceToClone.domainClass.grailsApplication.getDomainClass(newDomainInstance.getClass().name)
for (DefaultGrailsDomainClassProperty prop in domainClass?.getPersistentProperties()) {
if (notCloneable && prop.name in notCloneable) {
continue
}
if (bindOriginal && prop.name in bindOriginal) {
newDomainInstance."${prop.name}" = domainInstanceToClone."${prop.name}"
continue
}
if (prop.association) {
if (prop.owningSide) {
//we have to deep clone owned associations
if (prop.oneToOne) {
def newAssociationInstance = deepClone(domainInstanceToClone?."${prop.name}", notCloneable, bindOriginal)
newDomainInstance."${prop.name}" = newAssociationInstance
} else {
domainInstanceToClone."${prop.name}".each { associationInstance ->
def newAssociationInstance = deepClone(associationInstance, notCloneable, bindOriginal)
if (prop.oneToMany) {
if (newAssociationInstance) {
newDomainInstance."addTo${prop.name.capitalize()}"(newAssociationInstance)
}
} else {
newDomainInstance."${prop.name}" = 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, notCloneable, bindOriginal)
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 == "activationDate") {
newDomainInstance."${prop.name}" = new Date()
}
}
}
return newDomainInstance
}
사용 예제는 다음과 같습니다 -
Template cloneTemplate = cloneService.deepClone(originalTemplate,["id","name"],["parent"])
1 매개 변수 2 매개 변수를 복제 할 것입니다 원래 목적은 3 매개 변수 특성의 목록입니다 복제해서는 안 열 목록입니다입니다 is.eg로 참조되어야합니다. 템플릿은 복제 중에도 동일하게 유지되어야하는 일부 상위에 속할 수 있습니다.
복제 된 개체를 저장하려면 사용자 지정 요구 사항을 충족하는 다른 방법을 만드십시오. 다른 시나리오에서도 코드가 작동합니다.
"복제본"이란 무엇을 의미합니까? 귀하의 질문은 그 의미와 결과로서 기대되는 것을 설명하지 않습니다. –
어떻게 말을해야할지 모르겠지만 템플릿 (도메인 클래스)의 인스턴스를 가져 와서 관련된 모든 인스턴스의 값과 함께 모든 값을 복제 할 수 있기를 원합니다. 죄송합니다. 더 명확하지 않으면. – Jamie
아니, 지금은 꽤 분명합니다. 귀하의 필요를 충족시키는 것으로 보이는 다른 게시물을보고 싶을 수도 있습니다. http://stackoverflow.com/questions/20220711/proper-implementation-of-clone-for-domain-classes-to-duplicate-grails- 도메인 및 http://stackoverflow.com/questions/17614791/how-can-i-duplicate-a-domain-object-in-grails –