Hey, I ended up with doing silly things with Redis...
# server
j
Hey, I ended up with doing silly things with Redis and storing a changed class there with same key as earlier. This of course blew up my retrieval code as older versions could not be deserialized from JSON anymore. Any thoughts on how versioning of such (data?) classes could be automated? I am thinking of creating a simple object graph traversal that mostly allows for simple collections and basic types. But that seems like a lot of work for something that I think has been solved already. So what's the best way to store potentially changing Kotlin objects, serialized as JSON, to Redis?
a
Either make your parsing less strict so that deserialization doesn't blow up if properties have changed Or add some sort of version parameter - either to the key itself or as part of the header of the object - everytime the object is edited the version is bumped
j
Okay, it was kinda implied in my message that there's a version key there. What I am after is generating such a key from the class definitions. Idea being that then it would be easier to store all kinds of data. Other way to approach this is to have DAOish classes that are explicitly meant to store data and that you're more likely to remember to bump version in when you're making changes.
e
which type of serialization, java.io.Serialization or kotlinx.serialization?
if the former, serialVersionUID /
serialver
/
ObjectStreamClass.lookup(javaClass).serialVersionUID
is the key (either generated or manual) that goes with each class definition
if the latter, the
SerialDescriptor
is, which isn't written anywhere by default but it is also easier to evolve in a compatible way
j
We're talking about storing simple Kotlin objects as JSON to Redis. So serialization goes through Jackson here. What I am after is a way to generate "version" (can be a random string) whenever there are structural changes. Similarly to what you'd have in the old days where a Maven plugin would generate you serialVersionUID after a change. SerialDescriptor seems useful. In short, I would like to make it hard (or even impossible) to mix different versions of objects. One way to do this would be to have "version" a hash derived from shape of the data stored. Other way would be to manually add version fields to relevant classes and remember to always update them when needed.
e
I've never tried it before but from a glance, https://github.com/FasterXML/jackson-module-jsonSchema will generate a schema based off of your classes
j
I guess that would work
d
Different approach is to write a version upgrade function that you run against the redis server once only if you make a non compatible class change. Separate topic: If your using jackson serialization for redis, you have the full range of jackson annotations and datamapper at your disposal. I use jackson for all DTO's used for serializable API calls and redis storage ( redis via redisson). It take a little practice but I find that constructing classes (usually data classes) which are resilliant to upgrades or downgrades is generally not difficult. I find its easier to do so manually while Im making code changes and do not want it auto-generated for me. Why? Jackson supports features that allow you to make significant changes to the class structure while being able to serialize/deserialize the JSON without needing versioning. A simple example is adding a new field to a class. With proper use of default values you get version upgrade, with proper use of annotations or mapping feature you can get downgrade, e.g. 'ignore unknown fields' -- I have very rarely needed to version my data structures (maybe 3 times over five years and many hundreds of classes)