+ Start a Discussion
Neil Smith 10Neil Smith 10 

How to insert custom objects with a lookup to itself

I have a custom object called Questions. This object has a lookup to itself because a question can have additional questions which depend on their parent question. We need to insert 200+ at a time so I wrote an apex class that simply inserts the collection given to it:

global with sharing class QuestionRestController{
   global class RequestBody {
       global List<Question__c> questions;

    global static List<Question__c> createBulk(QuestionRestController.RequestBody req) {
        insert req.questions;
        return req.questions;

I get this error: System.DmlException: Insert failed. First exception on row 94; first error: INVALID_FIELD, Foreign key external ID: 966.0 not found for field MyExtId__c in entity Question__c no matter what I try.

I figured I could sort the questions before sending the request so that the parent questions are always inserted first but I still get the errors. I've added debug statements so I could verify the order of the questions prior to inserting and they are ordered correctly. I've also tried to insert each question by itself:

for (Question__c question: req.questions) {
    insert question;

But then I get a System.LimitException because I'm sending 200+ questions.

So what is the proper way to insert a list of custom objects which have a lookup to itself when the parent and child are both being inserted with the same request?

Bryn JonesBryn Jones

You can't make an object related to itself, because it is at the same heriearchiel level. Its a bit like trying to call your home phone number from your home phone , it doesnt work. You will need to create another custom object called questions Level 2, or something like that and then have the questions level 2 realte to level 1 questions.

Hope this makes sense.

Vinnie BVinnie B
I would think you would need a two step process.  First you would insert the questions themselves without any links to other questions.  Then, on a second pass you'd need to create some kind of map that allows you to link the questions together using the newly created IDs.
Hi Neil,

Try this : 
Questions  Q1 = new Questions (Name = 'Test2');

Questions Q2 = new Questions (name = 'test1');
Q1.QuestionsLookupfield= q2.id;


    results = Database.insert(new SObject[] {  q1, q2 });