We’ve all used dozens of serialization frameworks – for JSON, XML, binary, and ORM (which are actually serialization frameworks for relational databases). And there is always the moment when you need to exclude a field from an object – make it “transient”.
So far so good, but then comes the point where an object is used by multiple serialization frameworks within the same project / runtime. This is not necessarily the case, but first let me discuss the two alternatives:
- Use the same object for all serializations (JSON / XML for APIs, binary serialization for internal archiving, ORM / database) – best if there are only minor differences between serialized / persistent fields. Using the same object avoids many tedious transfers between DTOs.
- Use different DTOs for different serializations – this becomes a necessity as scenarios get more complex and using the same object becomes a patchwork of customizations and exceptions
Note that both strategies can exist within the same project – there are simple objects and complex objects, and you can only have a variety of DTOs for the latter. But let’s discuss the first option.
If each serialization framework has its own “transient” annotation, it is easy to change the serialization of one or two fields. More importantly, he will behave predictably. If not, you may be required to have separate DTOs even for classes where a field differs in behavior between serialization targets.
For example, the other day I had the following surprise: we use Java binary serialization (ObjectOutputStream) for internal buffering of large collections, and the objects are then indexed. In a completely separate part of the application, objects of the same class are indexed with additional properties that are not relevant for binary serialization and therefore marked with the transient Java modifier. It turns out that GSON respects the “transient” modifier and these fields are never indexed.
In conclusion, this article has two points. The first is: expect any behavior from serialization frameworks and test to verify different serialization scenarios. And the second is for framework designers – don’t reuse transient modifiers / annotations from the language itself or other frameworks, it’s counterintuitive.