Is there a way in apex to create a Map<Integer, Tuple<SObject1, SObject2>>
where the Integer is an index and the Tuple will hold the combination of SObjects. The process that I am trying to accomplish is where a trigger on SObject1 will try to create a record of type SObject2 and if SObject2 creation fails (DML exception), I want to be able to update the SObject1 status to error.
How: If the above map is possible, I can get the index of the Sobject2 record which failed and will be able to update SObject1 record at that index with the error status.
Is there a better way to do it? I am not sure if Tuples are allowed on the Salesforce platform. Any help is appreciated
Best Answer
Apex does not have the concept of a tuple, at least not natively.
You could try to create a wrapper class that holds both SObjects, or use a
Map<Integer, List<SObject>>
. Both of those approaches end up running into the same issue though; given an instance ofSObject2
, you wouldn't be able to (efficiently) find the correspondingSObject1
instance. I mean, linear time isn't the worst we could do, but we can find that correlation in constant time.You could tie them together using a
Map<SObject2, SObject1>
as mentioned in the comments on your question, but using SObjects as keys in a map is a dangerous game (if any field is changed by any amount, you'll lose the mapping, and I don't think you could get it back by undoing the change).Instead, I'd recommend simply using 2 separate lists. The first list holds your
SObject1
records. You'd iterate over that list to generate yourSObject2
records.The key here is that
Lists
are ordered collections. When you iterate over your first List, you start at index 0. When you addSObject2
to the second list, it too will be added starting at index 0. Assuming that you create only and exactly 1SObject2
record perSObject1
record, your two lists will be in lock-step with one another without the need for keeping an explicit index.Adrian, in the
catch
block of his example code, uses two methods from the DML Exception classgetNumDml()
andgetDmlIndex()
. Documentation on those can be found at the bottom of the documentation on built-in exception classes.getNumDml()
tells you how many failures you had, andgetDmlIndex()
tells you which index in the list you performed DML on was the cause of the exception.Putting everything together, we get something like
This approach doesn't assume that your two
SObjects
have any lasting relationship between them. If your twoSObjects
have some relationship (Master-Detail, Lookup, other...), then Adrian's approach may be better.