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
Aviator517Aviator517 

Attempt to violate heirachy constraint

I'm getting a weird issue with this bit of code. It's a visualforce controller, and on the visualforce page I have fields to insert/update 2 contact records. At the end I want one of the contact records, to be populated in a contact lookup on the 2nd contact page.

 

Here is the code:

public with sharing class ReferralFormController {
    Contact referrer;
    Contact candidate;
    List<SelectOption> referreroptions;
    
    public ReferralFormController() {
    // blank constructor
    }
    
    // the contact record you are adding values to
    public Contact getReferrer() {
        Id id = ApexPages.currentPage().getParameters().get('id');
        referrer = (id == null) ? new Contact() :
            [SELECT FirstName, LastName, Title, Personal_Email__c, Work_Email__c FROM Contact WHERE Id = :id];
        return referrer;    
    }
    public Contact getCandidate() {
        if(candidate == null) candidate = new Contact();
        return candidate;    
    }

    // save button is clicked
    public PageReference save() {
        try {
            Contact existingref = New Contact();
                for(Contact refchecker : [Select ID, FirstName, LastName, Title, Personal_Email__c, Work_Email__c
                                          From Contact
                                          Where Work_Email__c = :referrer.Work_Email__c OR
                                                Personal_Email__c = :referrer.Personal_Email__c OR
                                                (FirstName = :referrer.FirstName AND LastName = :referrer.LastName)
                                          LIMIT 1]){
                    existingref = refchecker;
                }
                if(existingref.Id != Null){
                    existingref.Title = 'Referrer Found!';
                update existingref;
                }
                if(existingref.Id == Null){
                    referrer.AccountId = '001L000000GFQip'; //change this when deploying to production!
                insert referrer;
                }
            Contact existingcan = New Contact();
            system.debug('CanFirstName =' + candidate.FirstName + 'CanLastName =' +candidate.LastName);
                for(Contact canchecker : [Select ID, FirstName, LastName, Title, Personal_Email__c, Work_Email__c  
                                          From Contact
                                          Where Work_Email__c = :candidate.Work_Email__c OR
                                                Personal_Email__c = :candidate.Personal_Email__c OR
                                                (FirstName = :candidate.FirstName AND LastName = :candidate.LastName)
                                          LIMIT 1]){
                    existingcan = canchecker;
                }
                system.debug('existing can =' + existingcan);
                if(existingcan.Id != Null){
                    existingcan.Title = 'It works a last time!';
                    if(existingcan.Referral_1__c == Null && existingref.Id != Null){
                        existingcan.Referral_1__c = existingref.id;
                    }
                    if(existingcan.Referral_1__c == Null && existingref.Id == Null){
                        existingcan.Referral_1__c = referrer.id;
                    }
                    if(existingcan.Referral_1__c != Null && existingref.Id != Null){
                        existingcan.Referral_2__c = existingref.id;
                    }
                    if(existingcan.Referral_1__c != Null && existingref.Id == Null){
                        existingcan.Referral_2__c = referrer.id;
                    }
                update existingcan;
                }
                if(existingcan.Id == Null){
                    candidate.AccountId = '001L000000GFQip'; //change this when deploying to production!
                    if(existingcan.Referral_1__c == Null && existingref.Id != Null){
                        existingcan.Referral_1__c = existingref.id;
                    }
                    if(existingcan.Referral_1__c == Null && existingref.Id == Null){
                        existingcan.Referral_1__c = referrer.id;
                    }
                    if(existingcan.Referral_1__c != Null && existingref.Id != Null){
                        existingcan.Referral_2__c = existingref.id;
                    }
                    if(existingcan.Referral_1__c != Null && existingref.Id == Null){
                        existingcan.Referral_2__c = referrer.id;
                    }
                insert candidate;
                }
    } catch (DMLException e) {
      ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error creating new contact.'));
      return null;
    }
    // if successfully inserted new contact, then displays the thank you page.
    return Page.referralthankyou;
  }
}

 

Not sure how the code as it currently stands (though probably very inneffient, so advice on improving would be great) could have the possibility to have a record reference itself?

 

Any help would be MUCH appreciated!

GunishGunish
HI,

This happens when you try and create a circular reference within the same object. e.g.
If
Contact has a lookup to Contact object itself and you have two contacts in the system
Contact A & B
Where you Populate Contact A's lookup to Contact B and Contact B's lookup field to Contact A.

This is generally only, unless there is a hierarchy based sharing rule activated on your object.

Can you give a brief description on what this code is trying to achieve, and then I can help you optimise it.

Regards,
Gunish
Aviator517Aviator517

Thanks for the reply! As I mentioned, I have a visualforce form that captures information for two contacts.

 

  • Referrer
  • Candidate

In the pagereference, I check to see if the referrer values are in Salesforce already, if so, I set existingref = to the record in the database currently. If nothing is found, I use the values stored in the "referrer" record captured by the form. (there may be a more efficient way to do this, but I'm not sure).

 

I then go and do basically the same operation for candidate, if it finds the record based on criteria in the SOQL query, I'll set existingcan = to the record it found, if not, I'll insert the values held in the "candidate" record captured from the form. At this time, I'd like to set the value of Referral 1, which is a contact lookup, (if null) equal to either existingref or referrer, depending on if a new record was needed to be inserted. If Referral 1 is already populated, I'd like to set the values in Referral 2.

 

Does that make sense?