While making VDUI Platform 2.x-compatible, I am stumbling upon this when saving an existing complex obs via REST:
ERROR - BaseRestController.handleException(115) |2016-10-07 19:58:46,756| Editing some fields on Obs is not allowed
org.openmrs.api.APIException: Editing some fields on Obs is not allowed
at org.openmrs.api.db.hibernate.ImmutableEntityInterceptor.onFlushDirty(ImmutableEntityInterceptor.java:111)
at org.openmrs.api.db.hibernate.ChainingInterceptor.onFlushDirty(ChainingInterceptor.java:75)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.invokeInterceptor(DefaultFlushEntityEventListener.java:365)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.handleInterception(DefaultFlushEntityEventListener.java:342)
...
I have tried to debug but so far I couldnât really figure out where exactly the thread is being interrupted. Does anyone know what the above error means?
Here is the full stack trace.
Actually the only field that is edited and attempted to be saved is the obs.comment.
This used to work fine with Core 1.11.x and our custom ComplexObsResource.
The high-level answer is that OpenMRS never intended to allow obs to be edited, but rather you must void-and-create-new for auditing purposes. Starting in platform 2.0 we actually enforce this (though I donât know the low-level details).
So, since we already have designed our own REST resource, would it be a good idea to expose a new âeditâ method through it that basically does what you said: â void-and-create-newâ?
What youâre trying to achieve is being able to revise an order and the rest API doesnât have a single call you can make to do so, you have to fetch the order you wish to revise, clone it, set the new field value(s), previousOrder and action on the clone and then post the clone. If youâre writing a java based client, cloning an obs for revision is a one line call to Obs.cloneForRevision() as shown in this test before you post it otherwise youâd have to replicate that code in your client.
Ooops! I donât understand why my brain was thinking about Orders, seems like I should go for the weekend, . Anyways, this might not be related but you need to update your resource to extend ObsResource1_11 if youâre running core 1.11+, this will continue to be a problem for you whenever we introduce a new version of the resource so you might want to figure out an alternative.
Back to your issue, in theory when you save an edited Obs, the API should automatically void and replace it but it seems like there is something wrong going on in your custom Obs handler, looking at this, the Obs has already been saved and then it sets valueComplex which am not sure if itâs setting a different value, seems like a possible cause of the issue.
The first one doesnât actually ever save the obs, it just saves its complex data. Meaning in this case saving a file on the disk. Then it sets the valueComplex to the obs object that shall be saved via the DAO layer.
This used to work fine with Core 1.11.x and actually still works fine on Platform 2.x when creating obs.
This leads me to think that the problem might rather come from what @darius suggested (although I donât know enough about the evolutions from Core 1.11.x to Platform 2.x to be sure) : it may not be possible to edit an obs via REST using our custom resource save(..) routine.
I meant: I think you should be able to POST to âŠ/obs/some-uuid and have this void-and-recreate (probably returning a redirect to the newly-created obs)
Iâm not sure if we did this yet⊠(and I havenât checked just now)
I am a little stuck with this, I would be grateful if you could shed some more light.
Coming back to my suggestion above in this thread:
How do I do that? What should I do to my custom resource so that in the end a new .edit(..)method is exposed on the Obs JavaScript object?
Anyway even if I keep overloading the existing .save(..) method I keep running on the same exception.
I have tried to customize the behaviour of Obs.save(Obs delegate) by simply saving a new copy of the delegate⊠and I get the exact same exception âEditing some fields on Obs is not allowedâ:
I was thinking that maybe it didnât like the UUID (since thatâs the one of the original obs), but in fact this line setting the UUID to null doesnât change anything.
The complexify(Obs) just fills in the complex data, removing it doesnât change anything either anyway.
I suspect there is something not right in our custom handler, the API automatically handles voiding and replacing the edited Obs, itâs not the REST APIâs job to do it
So I will make two unit tests, one for ComplexObsResource1_10 and one for ComplexObsResource2_0. The tests will just show that editing works with the former resource and fails with the latter resource (by hopefully generating the same APIException as mentioned above in this thread).
Hopefully this will help me figuring out where the change from 1.11.x to 2.x kicks in that breaks the behaviour of my custom resource and handlers.
However, Iâm already struggling with step 0 , please see this post.
@mksd, Iâm going to be offline +/- in full-day meetings all week, so I canât say much here. But others on this thread can help you better anyway. (And, as Daniel says, sharing a failing test is the way to go!)
Sure, hopefully Daniel will be able to help me setting up those tests.
I opened another thread about it as I ran straight away into yet another issue.
Thanks all for being on the fence, I really appreciate. I hope that Iâll be able to nail that Platform 2.x compatibility for VDUI by the end of the week. And after that I want to OWA-ize it
Some changes were made to Obs to make them immutable and yes itâs normal if your tests fail against 2.0, you can look at the logs after a failure to trace the line where everything bombs