TransientObjectException while accessing ProviderService in LegacyUI

Here is the code snippet which aims to accomplish the task of whether a provider with a given person exists. This is inside the showForm() method of UserFormController in Legacyui.

if(user.getPerson().getId() != null && !Context.getProviderService().getProvidersByPerson(user.getPerson()).isEmpty()) {
   model.addAttribute("isProvider", true);
} else {
   model.addAttribute("isProvider", false);
}

However, I get an error which says:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.openmrs.Person

The complete stack trace is here:

I had tried adding a Casacade Annotation as well but it seemed to fail (Maybe I added it at the wrong location?). Any help for this issue is appreciated. Also, why does this happen exactly? I have tried running the same code in the handleSubmission method and it works fine.

Can you give more details of when this happens because i.e does happen when you’re creating a new user or editing an existing user? And are you creating the user from an existing person or are you creating the person record too on the fly? You normally get this kind of exception when a persistent object is flushed to the DB with one of its associations is new (unknown to hibernate) and the flush can happen when you call any transactional method within the same session in your case you’re calling ProviderService.getProvidersByPerson() which cases the flush

@wyclif you can view the code here. And now, I’m not creating any new entries in the DB nor am I explicitly messing with persistent data IMO.

I still need to know under what scenarios you run into this or does it happen all the time regardless? Because i bet you wouldn’t run into where the person record already exists or if you’re creating a new user account

It happens why I try accessing the ‘Add User’ under ‘Manage User’ option in administration. Here is a screenshot:

So you’re saying when you click the Add User button but before you submit the form? And this only happens after your code changes?

Yes exactly. I have the PR mentioned there
you can try it

That info now helps, the problem is that in showForm() method there is 2 lines where you’re calling ProviderService.getProvidersByPerson(Person) when adding a new user account, the person object is new so the personId is null, this causes hibernate to complain since it requires the personId to join to the provider table. And also if you think about logically you don’t expect a non existent person to have a provider account, the ensuing if clause in your PR actually does the correct thing by first checking if it’s an existing person account before calling getProvidersByPerson

Aaah I see. I really need to check of the person exists tho. What’s a good workaround?

You’re already doing the correct check in the if clause right after those 2 calls to getProvidersByPerson(), just remove those 2 lines and it will be fine

I’m sorry I didn’t understand what kind I have to fix. You could you pinpoint it/comment on the PR?

Commented on the pull request for the 2 lines you need to remove

1 Like

I tested it and it works! Thanks :slight_smile: