Thursday 17 December 2015

You have reached the maximum number of 10 object references on ObjectName

We all love using Spanning Relationships(or Cross-Object References) while creating Formula Field, Validation Rules, Workflow Rules, Lookup Filters. Don't we?  


However there is a caveat which we should keep in mind before using it; and that is, "Salesforce allows a maximum of 10 unique relationships per object in cross-object formulas".
Some of you may agree with me here. I was very much uncomfortable in comprehending this limit. However I found this excellent Salesforce knowledge article which simplifies the way one should look at this limit.



                              Sharing the link here:  Understanding Spanning Relationships

Monday 14 December 2015

How to deal with: "System.TypeException: Cannot have more than 10 chunks in a single operation" in SFDC

In one of the interfaces, I designed and developed, between SFDC & SAP/PI, there was once incident where an end user encountered that her pricing agreement is not pushed to SAP.
When I looked into the Integration Logger object, I find this error message for the first time.


"Cannot have more than 10 chunks in a single operation. Please rearrange the data to reduce chunking.StackTrace:: Class.SfdcSapPricingInterface_Async.execute: line 2120, column 1"





When you go and look into SFDC document related to preparing list of SObjects, you will find that SFDC enforces a governor limit on the way it chunks different data types in the list<SObject>. Subsequently the number of data types that can be DML operated is limited to 10.


The order of the items in this list seems to play a part in the 'chunking'. It chunks everytime you switch object types.


Let's consider an example here. Keeping the same number of items in the list, If you are passing 12 items in a list of types A and B, this list contains 2 chunks:

          A, A, A, A, A, A, B, B, B, B, B, B  (which will not exceed this limit)

But this list contains 12 chunks:

          A, B, A, B, A, B, A, B, A, B, A, B  (which will exceed this limit)


You can find multiple solutions to this issue on the community forums et al. However I think a simple solution is this issue can be this:

     Just before your DML statement, sort your list of SObject:

               listSObjects.sort()
               insert/update listSObjects ;

This will align data of one type at one place together and other data type at other place. So in fact the chunking is now defined by number of data type present in list of SObject which can at max be 10.


Happy Apex coding   :) 

Tuesday 1 December 2015

Identify IP address in Salesforce.com Outbound Web Services

Last time with introduction of new SAP/PI client for our existing interface betweeen SFDC-SAP/PI, there was a need to re-establish the interface connection between the two systems. While making outbound callouts SFDC started getting; Web service callout failed: Unexpected element. Parser was expecting element 'http://schemas.xmlsoap.org/soap/envelope/:Envelope' but found ':html' error.
We all know very well when this type of exception happens. Usually this error occurs if there is some issue in communication with the external web service, there are a few things you can check.
  • Check if external webservice is really available and working.
  • Check if Salesforce's IP addresses are included in white list on the firewall of the network where the external web service is located.
  • Validate the endpoint address of the webservice.
  • Check if the endpoint's server is enabled as a Remote Site in Salesforce.
  • Remember that web service must be accessible from Internet to a public and valid IP address.


I suspected point #2. While troubleshooting network connection between Salesforce.com and SAP/PI, SAP says that they have white listed all SFDC recommended IP ranges in their firewall which prompted the question to identify which IP address SFDC instance was using to send request payload to the PI middleware. And this is very important task to do.
Go to your developer console and execute the below piece of code after setting remote site for the mentioned endpoint.
     HttpRequest req = new HttpRequest();
     req.setEndpoint('http://icanhazip.com/');
     req.setMethod('GET');
     Http httpReq = new Http();
     HttpResponse res = httpReq.send(req);
     System.debug(res.getBody());
For example, you will get something like this screen shot. Look for USER_DEBUG displaying the intended IP address, highlighted in yellow.

Later it was found out that this IP address was not white listed in PI firewall and thereby the issue was resolved. 
Some more info on icanhazip**
icanhazip.com is a service which can help you to find out your system's current external IP address. While setting endpoint; you can have a few options to choose from:
  • icanhazip.com – returns your IP address
  • icanhazptr.com – returns the reverse DNS record (PTR) for your IP
  • icanhaztrace.com – returns a traceroute from my servers to your IP address
  • icanhaztraceroute.com – returns a traceroute from my servers to your IP address
  • icanhazepoch.com – returns the epoch time (also called Unix time)
  • icanhazproxy.com – can determine if your traffic is being proxied

NOTE: If you want to force an IPv4 lookup, use ipv4.icanhazip.com. For IPv6, use ipv6.icanhazip.com.
Happy Apex debugging.. :) 
**referenced