Given optimistic concurrency using a version property and a json rest-service with a client that returns changesets consisting of the Id, Version and changed properties only, how can I update my server-side entity?
What I wanted to do was deserialize my json into a detatched entity and then use the ISession.Merge method to update my entity. However, my detached entity will have null-values for a lot of properties, and my entity will be updated with all of these if I call merge, which is not what I want. If there is a way to tell merge to ignore properties that are null and keep any corresponding non-null values from the persisted entity that would solve my problem.
If there is no way to configure the behaviour for merge, I could of course get the persisted entity and implement my own merging method using reflection. The problem with this approach is that it requires that I first query the db for the entity and then update it, whereas the merge method should do this as one operation unless I am mistaken.
You might ask why I want to pass only changesets instead of the complete entity. It is because it allows me to send minimal data and it also indicates explicity what the user is trying to change, which I can use for testing that users rights.
If it isn’t possible to do this within the bounds of nhibernate, how would you proceed?
I ended up using the WCF Web API for my application. I’m using a custom media formatter, wrapping Json.NET. This allows me to deserialize into generics and derived types, which is pretty awesome, and very usefull.
I have a
ChangeSetobject which has a few properties, the most important of which is a name-value Dictionary. With this setup I could define service operations takingChangeSetobjects. However I had to explicitly remove theXmlMediaFormatter. It was throwing errors, since it would not be able to deserialize such complex objects.After checking the users rights to change these properties, I fetch the object from the repository, update properties from the change-set, using reflection, and save it back to the repository.
Works beautifully if I’m being honest. 🙂