External Object – what is it?
Why did I choose to explore this topic? As a Salesforce developer, I work on a project in which External Objects are one of my everyday tasks. It’s an interesting task. However, I’ve managed to feel it on my own skin (or rather my code :)) that sometimes it’s not easy or can cause difficulties. I have several ways of tackling those challenges and I hope you find them useful.
But, for starters, what is an External Object? You create it when you want to use it in a Salesforce application built with data stored outside Salesforce. An External Object is usually a table. At first glance, it resembles a typical (standard) Salesforce object. However, it has only one common standard field – ID. The remaining standard fields are different (you can’t see such fields as Created Date and Owner, but you can see External ID and Display URL fields).
Why is it worth using External Objects?
In my opinion, there are three reasons. They all have one thing in common: save storage and time.
- Storage – you gain storage space; there is no need to store all data in Salesforce.
- Archive/external data – you access data quickly and easily.
- Processing outside Salesforce – you off-load the org that is already overloaded.
External Objects – huge possibilities, minor limitations
The benefits of using External Objects are far greater than minor inconveniences. The most important thing to know is that limitations exist and you need to keep them in mind during work. The main ones concern the following:
- Reports
They’re available, providing that you don’t disable the High Data Volume option on the OData adapter. - Security
Lack of Sharing Rules and the possibility of creating them (but with Cross Org adapters, only those rules that were created on the source org apply). You can implement authentication per user. Then, you can specify that each user needs to log in with their account to the database.
Object– and Field-Level Security settings are available as standard – you can define them on profiles and permission sets. They work in the same way as standard objects. - Limits
Query – searching for new records. Salesforce assigns them IDs when you search for them in external data sources. The limit equals 100,000 per hour divided between all sources. Adding new sources doesn’t increase the limit.
OData – callout – the limit equals 1K for the Developer Edition, 20K for the others. It’s a soft limit that can be increased.
Syncing – 200 objects per org.
Triggers – are unavailable in Salesforce, but you can create them in an external database.
Formulas – no possibility to create them.
It’s worth remembering that External Objects don’t support some functions. In such situations, you’re going to have a bit of manual work. The examples of such functions are as follows:
INCLUDES
LIKE
EXCLUDES
toLabel()
AVG
COUNT()
HAVING
GROUP BY
MAX()
MIN()
SUM().
External Objects configuration – several useful options
Let me start with the Custom Query Option (OData 2.0)/Free-Text Search Expressions (OData 4.0). They enable you to substitute the filter expression in a query to the external source (you can use any expression for the Custom Query Option and the search expression for the Free-Text Search Expressions). Salesforce recommends disabling these options. How does that help us? Imagine you have an External Object and use a global search. The object has 30 text fields (including 10 long text areas). What does the whole search process look like? Salesforce does that on all the text areas. Such a query overloads the database to a greater extent. When you select one of the above options, you can decide which fields you’re going to search.
High Data Volume is the next option. How does it work? It removes specified limits from Salesforce. If you enable it, the aforementioned limit of searching records up to 100,000 is not applied anymore – Salesforce stops assigning IDs to new records. But take a note: this option isn’t compatible with the Writable External Objects setting. In other words, you can’t enable it if you edit external records. In addition, the records won’t be available in Salesforce Lightning; they’ll be available in Salesforce Classic only.
An External Change Data Capture option can also be useful. It’s available for OData 4.0. As you know, triggers are unavailable. But when you use this option and the records are modified in the database, then, in Salesforce, you can see it as an event informing you about the change on the given object. It’s an event you can be very familiar with because it’s typical for Salesforce – Change Event. In this event, you can find information concerning how the object has been modified, deleted, or created, how fields have changed, and more. It’s important to remember that information refers only to those fields that aren’t empty (unless the content has been removed during an update). Moreover, OData adapters can’t distinguish between create and update. Therefore, an event always occurs as an update regardless of the type of update.
And finally, an option called Server Driven Pagination. Salesforce recommends using it and relying on pagination from external data sources. Why? When you process large collections, and simultaneously, something is added or deleted from the table, it can happen that some records are missed or processed twice.
External Objects configuration – what to pay attention to?
Here are my tips – I’ve chosen a couple of the most important ones for you. The first one concerns an ID. When you create an object, it receives an ID assigned by Salesforce. Regardless of the column name, there is also an External ID. Salesforce announced that, in the future, IDs assigned to objects would be temporary. Therefore, instead of relying on IDs received from Salesforce, you should rely on External IDs from external databases.
The next tip concerns resyncing objects. It’s worth pointing out that, in this case, the data types are overwritten. For example, in the external table, you can see data with a type of String/Text, where the object ID is stored in Salesforce. You sync such an object, receive a field with a type of Text, and map it on the Lookup. Assume that, in between, something has changed in the table, for example, new fields have been added. In such a situation, you sync again. As earlier, Salesforce overwrites them as a Text which causes breaking the relationship. That is why it’s better to create fields manually or add them on the test environment, and deploy them on the production environment, for example, by using a change set.
This process is similar to the Enable Search function. You can define the search on the data source and the same option on individual objects. In this way, you decide which objects are searchable in Salesforce. Then, if you uncheck this option on the selected object and sync it again, the value is overwritten by the value from the data source. It’s important not to clog up the database with unnecessary requests.
And last but not least – indexes. You don’t define them in Salesforce. Only indexes defined on the side of the external data source apply. Is it worth setting them up? Yes, if you want to make your search faster.
What you’ve just read was the subject of my presentation given on 27th January 2022 during SForce – Poland Salesforce Meetup. How about seeing my presentation? The video is available here: view it.
Author
- Salesforce Developer
-
Salesforce developer from the Craftware Academy. Graduated from Łódź University of Technology. He chose to work with Salesforce because, as he says, he still has too much hair on his head 🙂 Before that, he was a personal trainer. He’s very passionate about downhill mountain biking (an extreme form of mountain biking) and participates in this type of competition. When he doesn’t work, most probably, you can see him in the forest where he spends time bumping into trees and getting ready for the next races.