When deserialization goes wrong: Using the migration pipeline
As you know (hopefully), Sitecore XC stores all its entities as Json-serialized strings in the database. This makes it really flexible, as any components and policies you add to an entity are just serialized and stored. And if you need to change the entity, you deserialize it and the entity is again available to you to work with.
That is until you introduce something breaking. For instance, you decide to change the name of a component. Now, any serialized instance using the old name, cannot be deserialized. Now you have a problem, because how do you fix this?
IEntityMigrationPipeline
to the rescue!
Fortunately, there is a solution. The FindEntityPipeline
is responsible for retrieving an entity from the database. Within that pipeline, the DeserializeEntityBlock
does the deserialization of the entity. If, during deserialization, a JsonSerializationException
is thrown, the IEntityMigrationPipeline
is run. It takes a FindEntityArgument
as its input and returns the translated entity (if possible) as its output. This is what it looks like in my version of the Commerce Engine:
The IEntityMigrationPipeline
starts with the FindEntityJsonBlock
. This block retrieves the entity from the database and puts the Json as a string in the SerializedEntity
property of the FindEntityArgument
. Any block after the FindEntityJsonBlock
can be used to "fix" the Json so it can be deserialized and returned as the correct entity.
If you need an example on how to do this, the Commerce SDK contains a project called Plugin.Sample.Upgrade
which contains PatchEnvironmentJsonBlock
. This block patches the environment Json so that the type Sitecore.Commerce.Plugin.Customers.Cs.ProfilesSqlPolicy
is changed to Plugin.Sample.Customers.CsMigration.ProfilesSqlPolicy
.