LazyInitializationException error when loading order form in radiology module dcm4chee

Dear community,

OpenMRS Core Version: 1.10.2 (Currently Updating from 1.9.9) openmrs-module-radiologydcm4chee

when loading the radiologyOrderForm.jsp in radiologymoduledcm4chee we sometimes get the following exception

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.openmrs.Concept.names, no session or session was closed
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
        at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
        at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
        at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
        at org.openmrs.Concept.getNames(Concept.java:1090)
        at org.openmrs.Concept.getNames(Concept.java:1074)
        at org.openmrs.Concept.getName(Concept.java:529)
        ... 85 more

We use the openmrs: fieldGen for concept, patient, …

<form:form method="post" modelAttribute="radiologyOrder"
			cssClass="box">
			<table>
			<tr>
				<td><spring:message code="Order.concept" /></td>
				<td><spring:bind path="concept">
						<openmrs:fieldGen type="org.openmrs.Concept"
							formFieldName="${status.expression}"
							val="${status.editor.value}" />
						<c:if test="${status.errorMessage != ''}">
							<span class="error">${status.errorMessage}</span>
						</c:if>
					</spring:bind></td>
			</tr>

This LazyInitializationException occurs for any of the fieldGens.

How can we avoid this exception? What could be the cause?

You can avoid it by making sure that the Concept object is fully loaded when the controller ends its work. In this particular case, you must ensure all the names are loaded because the tag makes use of them.

The cause is that the Concept is an Hibernate proxy and the names collection is not initialized. When the custom tag tries to read it Hibernate detects that the session is closed. Not sure why the session is closed, in theory there’s a web filter that opens the session but I don’t know when it’s closed. Another solution is to make the tag aware of this situation and reload the object, possibly opening another session.

2 Likes

thanks again @lluismf! I now also found a wiki page regarding this exception if anybody else needs further infos: https://wiki.openmrs.org/display/docs/Troubleshooting+Exceptions

dear @lluismf, I just cant figure it out. I get this exception when I try to save a new RadiologyOrder, so the controller handling the get request passes a new RadiologyOrder object with concept = null to the view which renders fine. The user then chooses a concept via the org.openmrs.web.taglib.fieldgen.ConceptHandler, works fine as well (concept name is in the textbox). On saving the RadiologyOrder the LazyInitializationException occurs.

You said I should make sure that the Concept object is fully loaded. For a new Order there is no concept yet, so not sure what to do about that.

In an action of despair I tried to load all concepts and their names

for (Concept concept : conceptService.getAllConcepts()) {
	System.out.println("CONCEPTS:" + concept.getNames().size());
}

in the controllers get request method, which didnt solve the issue and is obviously not a nice solution anyway.

Do you have another suggestion?

You don’t need to load all concepts, only the one that’s associated to the order. I don’t know the exact flow of events, but for some reason the Concept was loaded in a previous Hibernate session and now is dettached. If you try to use its getters in the Controller you’ll probably get the same exception. To avoid this you may want to reattach the Concept to the current Session using the update method.

https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Session.html#update(java.lang.Object)

well it doesnt reach the controller handling the post request, exception occurs before when rendering the view. so I dont see what I can do inside the controller.

I found that in RadiologyOrder.hbm.xml

<hibernate-mapping package="org.openmrs.module.radiology">

<joined-subclass name="org.openmrs.module.radiology.RadiologyOrder"
	extends="org.openmrs.TestOrder" table="radiology_order" lazy="false">
	<key column="order_id" not-null="true" on-delete="cascade" />

	<one-to-one name="study" property-ref="radiologyOrder" />
</joined-subclass>

if I change the lazy property from “false” to “true” the exception does not occur anymore.

Does that make sense to you?

this was not the solution either :persevere: the exception simply does not always occur. if I spin up a fresh vagrant box, the exception might or might not happen. I think I need to change the jsp. I dont think I can do anything in the controller.

Changing the mapping is the easy solution, of course you’ll never find a LazyInitialization exception but it’s not recommended from a performance point of view.

I don’t see how changing the JSP will solve the problem. Maybe if you change the custom tag …