Loading

Fehler 'Cannot change field type' (Feldtyp kann nicht geändert werden) für Feld mit automatischer Nummerierung

Veröffentlichungsdatum: Dec 20, 2024
Beschreibung

Wenn der Datentyp eines Felds mit automatischer Nummerierung geändert wird, tritt der folgende Fehler auf, falls das Feld in Apex-Code referenziert wird:

Validation Errors While Saving Record(s) There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Cannot change field type of a custom field referenced in Apex class or trigger: AutoNumberTestMsg" (Validierungsfehler beim Speichern von Datensätzen – Beim Speichern der betroffenen Datensätze sind benutzerdefinierte Validierungsfehler aufgetreten. Der erste Validierungsfehler lautete "Feldtyp eines benutzerdefinierten Felds kann nicht geändert werden, das in der Apex-Klasse oder im Trigger referenziert wird: AutoNumberTestMsg").

Diese Probleme treten im Allgemeinen auf, wenn eine Datenmigration zu einer neuen Organisation erfolgt. Die Ursache hierfür ist das Vorhandensein eines Felds mit automatischer Nummerierung, das in Triggern und Apex-Code referenziert wird. Um dieses Feld laden zu können, muss der Typ jedoch in "Text" geändert, das Feld geladen und der Typ anschließend wieder zurück geändert werden. Der Apex-Code verhindert jedoch das Ändern des Datentyps. 
 
Einige der komplexesten Force.com-Bereitstellungsprobleme, mit denen der Kunde konfrontiert wird, hängen mit benutzerdefinierten Feldern des Typs "Automatische Nummerierung" zusammen. Die Werte in diesen Feldern können nicht aktualisiert werden, ohne zuvor ihren Typ vorübergehend in "Text" zu ändern. Wenn das Feld jedoch in Apex-Code referenziert wird, kann sein Typ überhaupt nicht geändert werden.
Mit einer dynamischen SOQL-Abfrage und den Methoden "get()" und "put()" ist dies jedoch möglich.
Lösung

Erstellen Sie zur Veranschaulichung der Technik ein benutzerdefiniertes Objekt "AutoNumberTest__c", mit dem experimentiert werden soll. Das Objekt sollte ein einzelnes benutzerdefiniertes Feld namens "autonumber__c" mit dem Typ "Automatische Nummerierung" aufweisen. Nach dem Erstellen des Objekts können Sie testen, ob der Typ des Felds "autonumber__c" ohne Probleme von "Automatische Nummerierung" in "Text" und anschließend wieder zurück in "Automatische Nummerierung" geändert werden kann. Dadurch können im Rahmen der Konvertierung oder Wiederherstellung bei Bedarf die nötigen Aktualisierungen vorgenommen werden. Hierzu sei gesagt, dass dies nicht für das Standardfeld "Name" gilt, für das ebenfalls der Typ "Automatische Nummerierung" festgelegt ist. Namensfelder werden anders behandelt als benutzerdefinierte Felder und das Attribut "Automatische Nummerierung" des Namensfelds kann geändert werden, ohne dass die Überprüfung des Typs durch den Apex-Compiler Probleme verursacht. Schreiben Sie nun einen Trigger "after insert" oder "after update" für ein Objekt "AutoNumberTest__c", das die Spalte "autonumber__c" referenziert. Im folgenden Beispielcode wird das Feld zum Erstellen eines Notizobjekts verwendet, das an das Objekt "AutoNumberTest__c" angehängt wird.
 
trigger AutoNumberTestMsg      on AutoNumberTest__c (after insert, after update) {  List newNotes = new List();  for (AutoNumberTest__c a : Trigger.new ) {    Note msg = new Note(      parentId = a.id,      title = '' + a.autonumber__c,      body = '' + a    );    newNotes.add(msg);  }  insert newNotes;}
 
Dieser Code durchläuft wiederholt alle neuen Werte im Trigger-Batch, erstellt ein neues Notizobjekt mit einer Zeichenfolgendarstellung des Objekts "AutoNumberTest__c" und fügt nach dem Durchlaufen sämtlicher Objekte die neuen Notizen in eine einzelne DML-Anweisung ein. (Der Ausdruck '' + a.autonumber__c" gibt eine Zeichenfolgendarstellung des Werts im Feld "autonumber__c" zurück.) Nach dem Erstellen dieses Auslösers tritt der folgende Fehler auf, wenn versucht wird, den Spaltentyp "Automatische Nummerierung" zu ändern:
 
Validation Errors While Saving Record(s)
There were custom validation error(s) encountered
while saving the affected record(s). The first validation
error encountered was "Cannot change field type of a
custom field referenced in Apex class or trigger:
AutoNumberTestMsg" (Validierungsfehler beim Speichern von Datensätzen – Beim Speichern der betroffenen Datensätze sind benutzerdefinierte Validierungsfehler aufgetreten. Der erste Validierungsfehler lautete "Feldtyp eines benutzerdefinierten Felds kann nicht geändert werden, das in der Apex-Klasse oder im Trigger referenziert wird: AutoNumberTestMsg").
 
In diesem speziellen Beispiel ist es sehr einfach, den vorhandenen Code auszukommentieren, den Feldtyp zu ändern, die Daten zu korrigieren und dann den Code auszukommentieren. Es ist selten einfach und gelegentlich nahezu unmöglich, wenn eine Höherstufung beteiligt ist oder der abhängige Code komplizierter ist.
Die Einführung der Methoden "Object.get()" und "Object.put()" in der Version Winter '09 bietet eine neue Alternative. Der Ausdruck "a.autonumber__c" kann zu "g.get('autonumber__c')" geändert und so den Compiler umgehen.
Der neue Trigger lautet wie folgt:
 
trigger AutoNumberTestMsg      on AutoNumberTest__c (after insert, after update) {  List newNotes = new List();  for (AutoNumberTest__c a : Trigger.new ) {    Note msg = new Note(      parentId = a.id,      title = '' + a.get('autonumber__c'),      body = '' + a    );    newNotes.add(msg);  }  insert newNotes;}
 
Es ist nun möglich, den Typ der Spalte "autonumber__c" zu ändern, ohne dass ein Fehler generiert wird.
Diese Änderung bringt natürlich eine neue Klasse von Laufzeitfehlern mit sich, die andernfalls vom Compiler verhindert worden wären. Wenn wir jetzt beispielsweise den API-Namen des Felds "autonumber__c" ändern, den Trigger jedoch nicht, verursacht der Code eine Laufzeitausnahme.
In realistischeren Szenarien sind die erforderlichen Änderungen in der Regel komplizierter und es besteht ein höheres Risiko für Laufzeitprobleme.
Betrachten wir beispielsweise folgenden SOQL-Ausdruck:
List aList =    [select id, autonumber__c from AutoNumberTest__c];
 
Hierdurch kommt es zu der gleichen durch den Compiler erzwungenen Einschränkung beim Ändern des Typs des Felds mit automatischer Nummerierung. Wir müssen auf dynamische SOQL-Abfragen und die Methode "Database.query()" zurückgreifen, um die direkte Referenzierung des Felds durch den Compiler zu vermeiden.
 
List aList =    Database.query('select id, autonumber__c from AutoNumberTest__c');
 
Der Wechsel zu dynamischen SOQL-Abfragen kann umständlich sein und außerdem schwieriger in der Handhabung sein. (Mit der Version Spring '09 können Sie in dynamischen SOQL-Abfragen die Interpolation mit ":" verwenden verwenden, was uns die Arbeit etwas erleichtert.) In Fällen, in denen ein Feld mit automatischer Nummerierung temporär geändert werden muss, um Aktualisierungen zu ermöglichen, ist der Wechsel zu dynamischen SOQL-Abfragen jedoch um einiges einfacher als früher.  

Siehe auch: 
Ändern von Standardfeldern mit automatischer Nummerierung
Nummer des Knowledge-Artikels

000385947

 
Laden
Salesforce Help | Article