Interest Manager – Importing Topic Types & Topics (Part 2: Running the Import)
Audience: Salesforce / technical admins
Prerequisite: A prepared CSV. See [Part 1 – Preparing Your Data]
Namespace: In a subscriber org, field and object API names start with
T1C_Base__
(e.g.T1C_Base__Topic_Mapping__c,T1C_Base__Status__c). The Apex below already uses the
namespace. Add the prefix in SOQL andwhereClausevalues.
There is no IM screen for this yet. Run each step from Setup → Data Import Wizard or the
Developer Console → Debug → Open Execute Anonymous Window.
Configuration (check once)
AFR feature ACE.FPM.Settings:
| Attribute | Default | Purpose |
|---|---|---|
ParentTypeName |
Flexible Preference |
Root Topic Type that every imported Topic Type sits under. Created automatically if it doesn't exist. |
NonCanonicalTypeNames |
(blank) | Comma-separated Topic Type Names whose Topics are deduped by tag path + value instead of type + name. Usually leave blank. |
Step 1 (optional): Generate a draft CSV from RiXML
- Upload the RiXML file as a Static Resource, e.g.
RIXMLSample. - Run:
T1C_Base.FPMServiceFacade.ServiceRequest req = new T1C_Base.FPMServiceFacade.ServiceRequest();
req.action = 'generateMappingPreview';
req.params.put('staticResourceName', 'RIXMLSample');
T1C_Base.FPMServiceFacade.ServiceResult res = T1C_Base.FPMServiceFacade.execute(req);
System.debug('ContentVersion Id: ' + res.data.get('fileId'));
- Download
RIXMLSample_MappingPreview.csvfrom Files. Every row defaults to
Status__c = Pending.Topic_Type_Name__cdefaults to the tag name with any@removed, and
Topic_Name__cdefaults to the tag value. - Hand the file to the business owner to curate (Part 1).
Step 2: Load the CSV into Topic Mapping
- Setup → Data Import Wizard → Launch Wizard.
- Custom Objects → Topic Mapping → Add new records.
- Upload the CSV and map each column to the field with the same name. Leave unmapped fields empty.
- Start Import.
For files over 50,000 rows, or for updating existing mapping rows, use Data Loader.
Step 3: Run the Topic Import
T1C_Base.FPMServiceFacade.ServiceRequest req = new T1C_Base.FPMServiceFacade.ServiceRequest();
req.action = 'runTopicImport';
// req.params.put('limitSize', 2000); // optional, default 2000 rows per run
T1C_Base.FPMServiceFacade.ServiceResult res = T1C_Base.FPMServiceFacade.execute(req);
System.debug(res.data); // {total, imported, skipped, failed}
Each run processes up to limitSize Pending rows. Repeat until total = 0.
What the import does:
- Validates
Topic_Type_Name__candTopic_Name__c. - Finds or creates each Topic Type, keyed by
Topic_Type_Unique_Key__cif you supplied one,
otherwise by Topic Type Name. - Finds or creates each Topic, keyed by
Type::Name, or for non-canonical types by a
SHA-256 hash ofTag_Path::Tag_Value. - Links each mapping row to its Topic Type and Topic and updates its Status.
- Creates parent/child relationships for rows that have
External_Id__candParent_Ids__c.
Step 4: Review results
SELECT T1C_Base__Status__c, COUNT(Id)
FROM T1C_Base__Topic_Mapping__c
GROUP BY T1C_Base__Status__c
SELECT Id, Name, T1C_Base__Topic_Type_Name__c, T1C_Base__Topic_Name__c,
T1C_Base__External_Id__c, T1C_Base__Notes__c
FROM T1C_Base__Topic_Mapping__c
WHERE T1C_Base__Status__c IN ('Error','Skipped')
| Status | Meaning | Action |
|---|---|---|
| Imported | Linked to a Topic Type and a Topic, whether newly created or already existing. | None |
| Error | See Notes__c, e.g. Missing Topic_Type_Name__c or Topic_Name__c or Failed to resolve topic. |
Fix the row, set it back to Pending, re-run Step 3. |
| Skipped | The parent Topic Type (ParentTypeName) could not be created. Nothing was imported. |
Check the AFR setting and permissions, reset the rows to Pending, re-run. |
| Pending | Not processed yet (over limitSize). |
Re-run Step 3. |
Notes__c on imported rows also reports relationship results: Relationships created: N,
No new relationships (already exist), or Relationship errors: Missing parent: X.
Step 5 (optional): Repair parent/child relationships
Relationships are built only when the parent row is already Imported. If a parent failed or
was loaded in a later file, fix it, import it, then run:
T1C_Base.FPMServiceFacade.ServiceRequest req = new T1C_Base.FPMServiceFacade.ServiceRequest();
req.action = 'repairRelationships';
// Optional filter, any SOQL condition on Topic_Mapping__c:
// req.params.put('whereClause', 'T1C_Base__Topic_Type_Name__c = \'Region\'');
// req.params.put('whereClause', 'T1C_Base__External_Id__c IN (\'RGN-NA\',\'CTY-US\')');
// req.params.put('whereClause', 'CreatedDate = TODAY');
T1C_Base.FPMServiceFacade.ServiceResult res = T1C_Base.FPMServiceFacade.execute(req);
System.debug(res.data); // {totalMappings, created, alreadyExist, unresolved, errors}
This step is safe to re-run. Existing relationships are not duplicated.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Two Topic Types that look the same | Names differ by case or spacing, e.g. Asset Class and Asset class. |
| Topics that should merge stayed separate | Topic Names differ slightly, or the type is listed in NonCanonicalTypeNames. |
| Topics that should be separate merged | Same Type + Name under a canonical type. Use distinct names, or add the type to NonCanonicalTypeNames and supply Tag_Path__c/Tag_Value__c. |
| Row loaded but never imported | Status__c was blank or not Pending. |
| Missing parent: X in Notes | No Imported mapping row has External_Id__c = X. Import it, then run Step 5. |
Clean-up (optional)
Keep imported Topic Mapping rows as an audit trail, or delete them once you have verified the
Topics. Also delete the RiXML Static Resource and the preview CSV file once you no longer need them.