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

Adding elements to a list


This is my first post, but I want to thank all the contributors for the countless times I have found something useful here.  Here is the issue I am experiencing:

I am using a trigger to create two manual sharing rules in the OpportunityShares object by adding the necessary properties to list elements. The list is of sObject type OpportunityShares and called newOppShrs.   First I set the properties for one, then add it to the list, then I resue the same OpportunityShares sObject (called partnerShare) and add it to the list.  Although I am adding two separate records to the sObject list, I'm receiving an error regarding adding duplicate records into the OpportunityShares table.  Additionally, debug logs show me that both elements in my list are identical (the second element is what is attempting to be written to the OppShares table), confirming that I'm not doing something right when adding these elements.  I've confirmed that at the time I'm adding the elements to my list the values are unique for UserOrGroupId.  Here is the (partial) code that is causing the error.



//Access the Contact/User Map using the Allocator's
//contact Id from Allocator__c to get the
//value of the corresponding user's ID and add the
//property to the partnerShare object and add the record
//to to the newOppShares list of OpportunityShare records

if (o.Allocator__c != null){
	system.debug('Alloc Shr Add ' + contactToUserMap.get(o.Allocator__c));
	partnerShare.UserOrGroupId = contactToUserMap.get(o.Allocator__c);
	partnerShare.OpportunityAccessLevel = 'Edit';
	system.debug('partnershare Alloc = ' + partnerShare.UserOrGroupId +
	 ' ' + partnerShare.OpportunityAccessLevel);			
//Do it again for the Underwriter
if (o.Underwriter__c != null){
	system.debug('Underw Shr Add ' + contactToUserMap.get(o.Underwriter__c));
	partnerShare.UserOrGroupId = contactToUserMap.get(o.Underwriter__c);
	partnerShare.OpportunityAccessLevel = 'Edit';
	system.debug('partnershare Alloc = ' + partnerShare.UserOrGroupId + 
	' ' + partnerShare.OpportunityAccessLevel);

//Add'l Debug
for(OpportunityShare os : newOppShrs){
	system.debug('OpportunityId = ' + os.OpportunityId + ' ' + 'UserOrGroupId = ' + os.UserOrGroupId);}

//Perform the DML operation, adding both records
		insert newOppShrs;
	catch (DMLException DMLe){
		system.assert(true,'Caught DML Exception: '+DMle.getDMLMessage(0));
        	system.debug('\n\nCaught DML Exception: '+DMle.getDMLMessage(0));



FYI, I can make this work by re-instantiating the partnerShare sObject between adding the allocator and underwriter elements by adding the following:



partnerShare = new OpportunityShare();
partnerShare.OpportunityId = o.Id; //I also do this before the first code snippet)


 What I can't understand is why I have to do that.  Shouldn't I be able to reuse it?

Thanks in advance,



Best Answer chosen by Admin (Salesforce Developers) 
Jake GmerekJake Gmerek

You are correct in that you can reuse it but the problem is that the ID of the record never changes.  You create one new record, edit some properties in the Allocator code section add the record to the list and then edit some more properties and then add the same record to the list as a second item.  Then when you call your insert it is trying to insert the same record two times.  So in short yes, the easist way is to reallocate the variable so that it points to a second object.


What you have to remember in this situation is that the variable is just a reference to the object (it is sort of confusing but in this context we are talking about a programmatic object not a SF Object, so the object I am referring to is the actual record you are inserting into salesforce) in memory, when you change the properties of the object you are not changing the variable at all, you are changing the object in memory, so unless you direct the variable to reference a different object you are still working with the same object.  If you ever programmed in C or C++ it is sort of like a pointer.


Hope this explained your problem