What happens when you update an Extended Table record to change the Class?Issue This article aims to explain what happens when an extended table record has it's Class/Task Type [sys_class_name] field updated to move the record to a different table with the extended table hierarchy, in order to aid debugging and avoid potential problems. From the CMDB point of view, this is referred to as Reclassifying a CI, where the class may be upgraded, downgraded or switched, depending on where you are moving the record to in the hierarchy. There are over a hundred extended tables in the instance, with over a thousand child tables. Once you understand the Extension Models, you will realize that changing this field value in effect moves the record from one table to another. In general, these steps happen when an existing record is updated with a new Class value. A user or script in the instance, makes an update to an existing record. The sys_class_name value will be changed, plus potentially other fields.Before Update business rules run for the previous class. Engines at before 1000 also run. Async and After business rules don't run.GlideRecordClassSwitcher switchClass() runs: Does some checksLogs "Change in class detected, switching from: <previous.sys_class_name> to: <current.sys_class_name> sys_id: <sys_id>"Update any external records for multi value fields, such as Currency field values.Read all the record values into memoryDelete the record from the previous class table. Without running business rules etc.Insert a new record using all the previous values of the original record. Without running business rules etc.If the old record has attachments, assign them to the new record.Update the newly inserted record (this is in addition to the initial update) Run Before Update Business Rules for the new classAudit the update.Run After Update Business Rules for the new class Related LinksGiven that process, it explains why the following happens: 'Before' Business Rules run Twice The initial update by the user or script Before Update business rules for the source table The additional update by the class changing code Before Update business rules for the target tableAfter Update business rules for the target tableAsync Update business rules for the target table .setWorkflow(false) will not prevent Business Rules or Auditing running This method "Enables or disables the running of business rules that might normally be triggered by subsequent actions. If the e parameter is set to false, an insert/update will not be audited. Auditing only happens when the parameter is set to true for a GlideRecord operation." If you do the class change update from a script, and use setWorkflow(false) before the .update(), this will only prevent the before update business rules running for the source table. This has no effect on the additional Update() the class changing code does after inserting the new record. Before, After and Async business rules for the target table will still run for the record. There is no way to prevent that. If batch updating a lot of records, you may want to analyse which business rules will run (using Session Debug perhaps) and De-activate long-running or potentially problematic ones while the updates run. .autoSysFields(false) will not prevent updating the Updated/Updated By/etc. fields This function "Enables or disables the update to the fields sys_updated_by, sys_updated_on, sys_mod_count, sys_created_by, and sys_created_on. This is often used for manually updating field values on a record while leaving historical information unchanged." As with setWorkflow(false), this would only apply to the initial update. The subsequent insert and update are going to have new values populated. sys_created_on will be when this runs, and sys_mod_)count will be back to zero. "Class Changes" Filter Conditions in a run After business rule won't trigger By the time after update business rules run, the update is in effect running for an insert, where the class is not changing. This confuses the Filter Conditions. However if you script the Condition instead, it will trigger. Condition: current.sys_class_name.changes(); Data loss - Fields don't exist in the new class If fields that existed in the previous class don't exist in the new class, then those values are lost. e.g. a cmdb_ci_win_server to cmdb_ci_ip_switch reclassification will loose fields such as cpu_name and host_name. Data Loss - The record could be Deleted during this process, if the Insert fails As explained above, the record is first deleted from the source table and then inserted in the target table. Various things could cause the insert to not happen, after the delete has already happened, meaning your record is now lost. The transaction could time out or be Cancelled by the user before the Insert happens. This was seen more often from Jakarta, but was possible prior to that too.London and later versions should prevent this. see KB0727782: PRB1242353 When changing the class for many CIs from UI it may lead to transaction cancellation and deletion of few recordsData Policy, with Mandatory field rules, could prevent the insert. This is a known product defect - see KB0727701: PRB631444 Changing the sys_class_name of a record can result in the record being deleted if Mandatory fiel Data Policy prevents the insert in the target table It can take a long time per record A class change for a single record may take just a second, but can take minutes to run. That could be due to business rules running, and session debug would identify which to investigate. In Jakarta (when TPP was used) and Kingston, an analysis of database logs usually shows most of the time spent doing a lot of queries on the Dictionary and related tables during the Delete step, due to the multiple additional dictionary records used by this model. That has been improved from London by KB0681177: PRB1258222 Unnecessary updates during cmdb_ci class change from TPP change Audit records from before the Class change may appear to be missing Audits are logged with the table name it was at the time. Any sys_audit records from before the change are not updated to the new table name. The code that generates the History Set and Lines knows to take this into account. Features such as History List, Activity formatter, CMDB Timeline, CMDB Baseline Diff etc. use the history set, and so should also work. If you are querying the sys_audit table directly using the new table name, then you will only see records since the change. Use the sys_id (document_key) only. If the previous or current class Tables are not set as Audited in the Dictionary, then you also can't expect a full audit history.