Maintain Backward and Forward Compatibility Between Class Definitions
Revising a class definition can lead to errors when trying to deserialize instances of a
different version of that class using the default load process. When changing a class
definition, you can inherit from matlab.mixin.CustomElementSerialization and use it to control how the new class
definition serializes and deserializes instances to preserve compatibility. The general
process is:
When you revise your class definition in a way that breaks compatibility with the older version, add
matlab.mixin.CustomElementSerializationas a superclass.If you need to change how objects of the revised class are serialized, implement the
modifyOutgoingSerializationContentmethod ofmatlab.mixin.CustomElementSerialization. The method takes an instance ofmatlab.serialization.ElementSerializationContentas input. That object represents what will be serialized, and the methods ofmatlab.serialization.ElementSerializationContentenable you to change how properties are serialized.If you need to change how objects of the revised class are deserialized, implement the
modifyIncomingSerializationContentmethod ofmatlab.mixin.CustomElementSerialization. The method takes an instance of thematlab.serialization.ElementSerializationContentclass as input. That object represents what will be deserialized, and the methods ofmatlab.serialization.ElementSerializationContentenable you to change how properties are deserialized.If you need to perform any final operations on the deserialized object, such as adding an event listener, implement the
finalizeIncomingObjectmethod ofmatlab.mixin.CustomElementSerialization. The method takes the deserialized object as input.
Backward Compatibility
Define a class Employee that stores basic information. The
EmployeeID property is stored as a string with
"ID-" at the beginning, as shown by the default value.
classdef Employee properties Name Department EmployeeID = "ID-0000" Email end end
Create an instance of Employee, assign values to all the properties,
and save it. Replace yourfilepath with your local
path.
eOld = Employee;
eOld.Name = "Alex Cruz";
eOld.Department = "Sales";
eOld.EmployeeID = "ID-1301"
eOld.Email = "acruz@notacompany.com"
save("yourfilepath/oldEmployee.mat","eOld");Update the class definition with new and redefined properties:
Split
NameintoFirstNameandLastName.Change
DepartmenttoDivision.Remove the "
ID-" prefix from theEmployeeIDproperty.
Trying to deserialize an object that was serialized under the old definition would
leave some properties without proper values. To keep the old objects as accessible as
possible, add matlab.mixin.CustomElementSerialization as a superclass and
implement the static method modifyIncomingSerialization to convert the
old property data into the new format as needed.
classdef Employee < matlab.mixin.CustomElementSerialization properties LastName FirstName EmployeeID Division Email end methods (Static) function modifyIncomingSerializationContent(sObj) if sObj.hasNameValue("Name") nameArray = split(sObj.Name); sObj.addNameValue("FirstName",nameArray(1)); sObj.addNameValue("LastName",nameArray(2)); sObj.remove("Name"); sObj.rename("Department","Division"); id = split(sObj.EmployeeID,"-"); sObj.updateValue("EmployeeID",id(2)); end end end end
MATLAB® calls modifyIncomingSerializationContent when you load an
object of Employee. The method takes as input an instance of matlab.serialization.ElementSerializationContent. The
hasNameValue method of
matlab.serialization.ElementSerializationContent checks to see if the
saved object has a property called Name. If there is a
Name property, the object being deserialized was serialized
under the old class definition. In that case, the methods of
matlab.serialization.ElementSerializationContent convert and assign
the old property data into the revised properties:
The value of the
Nameproperty is split into an array of two strings, and theaddNameValuemethod adds theFirstNameandLastNameproperties.removediscards the old propertyName.The
renamemethod changesDepartmenttoDivision.The
updateValuemethod changes the value of theEmployeeIDproperty to include only the numeric portion.
Clear eOld from
memory.
clear("eOld")Employee from your path. Add the revised definition of
Employee to the path, and load the eOld object.
Display the object to confirm that the variable has been deserialized as an object of
the revised definition of Employee.load("yourfilepath/oldEmployee.mat","eOld")
eOldeOld =
Employee with properties:
LastName: "Cruz"
FirstName: "Alex"
EmployeeID: "1301"
Division: "Sales"
Email: "acruz@notacompany.com"matlab.mixin.CustomElementSerialization also provides a static
finalizeIncomingObject method. If the method is implemented,
MATLAB calls it after modifyIncomingSerializationContent. Use
the method to perform any necessary cleanup on the deserialized object, like restoring
property listeners, for example. In the case of Employee,
finalizeIncomingObject could be used to fill in the unknown value
for EmployeeID if the method has access to that data from other
sources.
The modifyOutgoingSerializationContent method also has an optional
input argument, an instance of matlab.serialization.SerializationContext. An instance of this class can be
used to determine the context in which the object is being serialized. For example,
MATLAB sets the CustomizeForReadability property of the
instance to true if the serialized object is readable by external
users.
For an additional example on preserving backward compatibility, see Load Serialized Objects After Changing Class Definition.
Forward Compatibility
The latest version of Employee can now successfully deserialize
objects saved under the older version of the class, but the class does not have forward
compatibility. In other words, someone who only has access to the older version of the
class cannot successfully deserialize an object serialized under the latest version of
the class.
To support forward compatibility, implement the
modifyOutgoingSerializationContent method of
matlab.mixin.CustomElementSerialization in the new class definition.
This method controls what information is serialized, so the goal is to save the
information in a way that both the old and new versions of the class can access.
MATLAB calls modifyOutgoingSerializationContent when you save an
object of Employee. The method takes as inputs an object of matlab.serialization.ElementSerializationContent as well as the object
itself. The process from there is the inverse of how
modifyIncomingSerializationContent works. The properties are
reverted to the format of the older version so that the data can be deserialized by
either version of the class.
classdef Employee < matlab.mixin.CustomElementSerialization properties LastName FirstName EmployeeID = "0000" Division Email end methods (Static) function modifyIncomingSerializationContent(sObj) if sObj.hasNameValue("Name") nameArray = split(sObj.Name); sObj.addNameValue("FirstName",nameArray(1)); sObj.addNameValue("LastName",nameArray(2)); sObj.remove("Name"); sObj.rename("Department","Division"); id = split(sObj.EmployeeID,"-"); sObj.updateValue("EmployeeID",id(2)); end end function modifyOutgoingSerializationContent(sObj,obj) nameStr = append(obj.FirstName," ",obj.LastName); sObj.addNameValue("Name",nameStr); sObj.remove("FirstName"); sObj.remove("LastName"); sObj.rename("Division","Department"); fullID = append("ID-",obj.EmployeeID); sObj.updateValue("EmployeeID",fullID); end end end
Resave eOld under the newer definition of
Employee and then load it under the older class definition. The
deserialized version under the older definition is in the correct format.
eOld =
Employee with properties:
Name: "Alex Cruz"
Department: "Sales"
EmployeeID: "ID-1301"
Email: "acruz@notacompany.com"For another example of a revised class definition that supports both forward and backward compatibility, see Maintain Backward and Forward Compatibility During Serialization.
See Also
matlab.mixin.CustomElementSerialization | matlab.serialization.ElementSerializationContent | matlab.serialization.SerializationContext