function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
WilmerWilmer 

How to reparent a master-detail field with Dynamic DML

Hi, I'm working in a customized trasfering process and I tried to make it by Dynamic DML operation. In spite of I have already enable the "Allow reparent checkbox attribute at the master-detail field, I got an error llike: "Invalid field  for ChildObject__c" (seems like no field name were given).

Here is my sample code:
public class myTransferClass_cls{

public void fnTransfer(){
id TargetAccId = 'myTargetAccountId'; // this is an Id

// Get the records to be transferred
Account SourceAcc : [SELECT Id, Name, 
	// Related Plans: Planes asociados
	(SELECT Id, ParentId__c FROM ChildRecords__r)
	FROM Account
	WHERE Id = 'mySourceAccId' LIMIT 1];

myTransferClass_cls  ctr = new myTransferClass_cls();
ctr.transferChildRecords(SourceAcc.ChildRecords__r, TargetAccId, 'ChildObject__c', 'ParentId__c');
}

// Here is the generic Method to transfer child records
private integer transferChildRecords(list<sObject> RecordsToTransfer_lst, id TargetPatientId, string strObjectName, string strParentFieldName){
		integer intTransferredRecords = 0;
		
		if(!RecordsToTransfer_lst.isEmpty()){

			for(sObject record : RecordsToTransfer_lst){
				record.put(strParentFieldName, TargetPatientId);
			}
			system.debug('*** NEW RecordsToTransfer VALUES: '+RecordsToTransfer_lst);
			update RecordsToTransfer_lst;
			intTransferredRecords = RecordsToTransfer_lst.size();
		}
		
		return intTransferredRecords;
	}
}
Any ideas? or it's not possible to do it with Dynamic DML by now?

Thanks for your help.

Regards,

Wilmer






 
Abhishek BansalAbhishek Bansal
Hi Wilmer,

Please change your code with the below code :
 
public class myTransferClass_cls{
	public void fnTransfer(){
		Id TargetAccId = 'myTargetAccountId'; // this is an Id

		// Get the records to be transferred
		Account SourceAcc = [SELECT Id, Name, 
			// Related Plans: Planes asociados
			(SELECT Id, ParentId__c FROM ChildRecords__r)
			FROM Account
			WHERE Id = 'mySourceAccId' LIMIT 1];
		Integre noOfRecords = transferRecords(SourceAcc, TargetAccId);
	}
	private Integer transferRecords(Account sourceAccount, Id parentAccountId){
		for(ChildRecords__c child : sourceAccount.ChildRecords__r){//Replace ChildRecords__c with API Name of your child object
			child.Account__c = parentAccountId;//Replace Account__c with Api name of your Account lookup field on child Objec
		}
		update sourceAccount.ChildRecords__r;
		return sourceAccount.ChildRecords__r.size();
	}
}

Let me know if you need more help.

Regards,
Abhishek Bansal
WilmerWilmer
Hi Abhishek,

Thanks for your help.

I agree with you that it seems at this moment it is not possible to do it totally dynamic as I suggest in my code. The way you show me is the one I had to choose for now, so that means that if you require to transfer many child records from different child Objects, the only way is to write as many methods as child objects you have or using the code youo suggest, could be only one with an additional parameter in order to handle internally the sobejct type you need to process.
 
// Method to transfer child records
	private Integer transferRecords(Account sourceAccount, Id parentAccountId, string strChildObjectName){
		integer intTransferedRecords = 0;
		if(strChildObjectName == 'ChildObject1__c'){
			for(ChildRecords1__c child1 : sourceAccount.ChildRecords1__r){//Replace ChildRecords1__c with API Name of your first child object
				child1.AccountId__c = parentAccountId;//Replace AccountId__c with Api name of your Account lookup field on child Object
			}
			update sourceAccount.ChildRecords1__r;
			intTransferedRecords = sourceAccount.ChildRecords1__r.size();
		}else if(strChildObjectName == 'ChildObject2__c'){
			for(ChildRecords2__c child2 : sourceAccount.ChildRecords2__r){//second child object
				child2.AccountId__c = parentAccountId;//Replace AccountId__c with Api name of your Account lookup field on child Object
			}
			update sourceAccount.ChildRecords2__r;
			intTransferedRecords = sourceAccount.ChildRecords2__r.size();
		}
		return intTransferedRecords;
	}
So in conclusion, what I was trying to do was to optimize my code by using an unique transfer Method no mather the child object was.

If you have any suggestion I would appreciate it, if not, then we could mark thyis option as the workarround for this scenario.

Regards,

Wilmer



 
Abhishek BansalAbhishek Bansal
Hi Wilmer,

Since our requirement will always be specific to certain objects so we cant use dynamic method.
Yes i would also suggest you to go with the above approach and will suggest you to just a liitle change.
Please change line no. 9 and 15 with below line :
intTransferedRecords += sourceAccount.ChildRecords2__r.size();

In this way we will have the total number of records that have been updated in a particular context and we can easily handle the salesforce governor limits.

Let me know if you still have any queries.
If not, than you can close this question.

Regards,
Abhishek.