/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs;
import java.lang.reflect.Field;
import javax.annotation.PostConstruct;
import org.hibernate.SessionFactory;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostLoadEvent;
import org.hibernate.event.spi.PostLoadEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Hibernate by default calls setters when initializing a persistent entity from the database
* meaning an Obs would be marked dirty the first time it's loaded by hibernate, therefore we need
* to use an instance of this PostLoadEventListener to mark an Obs as not dirty when it gets loaded.
*
* <pre>
* Note that in hibernate 4, event listeners are now registered via the new integrator and service
* capabilities which leverage Java's standard java.util.ServiceLoader mechanism to discover then
* but unfortunately spring hasn't caught up with these integrator capabilities therefore we need to
* manually 'springfy' the registration of our EventListener
* </pre>
*/
@Component
public class ObsPostLoadEventListener implements PostLoadEventListener {
private static final Logger log = LoggerFactory.getLogger(ObsPostLoadEventListener.class);
@Autowired
private SessionFactory sessionFactory;
@PostConstruct
public void registerListener() {
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.POST_LOAD).appendListener(this);
}
@Override
public void onPostLoad(PostLoadEvent event) {
if (Obs.class.isAssignableFrom(event.getEntity().getClass())) {
Field field = null;
try {
field = Obs.class.getDeclaredField("dirty");
field.setAccessible(true);
field.set(event.getEntity(), false);
}
catch (ReflectiveOperationException e) {
log.error("Failed to unset an Obs as dirty after being loaded from the database", e);
}
finally {
if (field != null) {
field.setAccessible(false);
}
}
}
}
}