Database event handling by spring

I want to handle database events with spring. spring has event handling mechanism and I have defined some custom event handlers in spring. for example if an employee gets inactivate in system so certain sets of activity are required to perform so is there any way in which spring custom event listners can be fired. I am using spring with hibernate. I suspect if there could be a way in hibernate to achieve this but i want to handle it spring. Thanks in advance

Answers


If I understand your question correctly, you need to know a way to intercept hibernate entity change event and trigger an event which can be handled by Spring. You can always intercept events in hibernate i.e., inspect and/or change property values of hibernate entity elements using Interceptor. For example, Employee entity has status(say String) field, you can detect change(say, changed from active to inactive) to this field and perform some action before change can be persisted to database. Changes to any collection present in this entity can be intercepted as well. For brevity I am taking up only field change.

Define a listener interface FieldChangeListener for field change tracking as:

    public interface FieldChangeListener<T>{
        /**
         *  Defining generically so that it can be implemented by any entity on which field change needs to be observed.     
         * @param propertyName - the property name on the entity    
         * @param entity - the entity object    
         * @param previousState - the old value    
         * @param currentState - the new value    
         * */  
            void onChange(Object[] previousState, Object[] currentState, String[] propertyName, Type[] types, Object entity);    
    } 

In order to use said Interceptor, we need to create a class that extends EmptyInterceptor:

    public class FieldChangeInterceptor extends EmptyInterceptor {
        private Map<Class, FieldChangeListener<?>> listeners;       

        public void setListeners(Map<Class, FieldChangeListener<?>> listeners) {
            this.listeners = listeners;
        }

        @Override
        public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {       
            FieldChangeListener<?> listener = listeners.get(entity.getClass());
            boolean report = false;
            // Only check for changes if an entity-specific listener was registered.
            if (listener != null) {
                listener.onChange(previousState, currentState, propertyNames, types, entity);
                report = true;
            }
            return report;
        }   
    }

Define the interceptor and listener(s) in your context xml as:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        ...
    </bean>
    <bean id="fieldInterceptor" class="package.FieldChangeInterceptor">
        <property name="listeners">
            <util:map id="listeners" map-class="java.util.HashMap">
                <entry>
                    <key><value>package.Employee</value></key><ref bean="employeeListener"/>
                </entry>                
            </util:map>
        </property>
    </bean> 
    <bean id="employeeListener" class="package.listener.EmployeeListener"/>

EmployeeListener class is:

    public class EmployeeListener implements FieldChangeListener<Employee>, ApplicationEventPublisherAware{         

        private ApplicationEventPublisher publisher;
        public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
            this.publisher = publisher;
        }

        @Override
        public void onChange(Object[] previousState, Object[] currentState, String[] propertyName, Type[] types, Object obj) {
            log.info("Enter onChange()...");
            Employee employee = (Employee)obj;
            boolean isChange = false;
            for (int i = 0; i < currentState.length; i++) {
                if (currentState[i] == null) {
                    if (previousState[i] != null){
                        isChange = true;
                    }else{
                        isChange = false;
                    }
                } else if (!currentState[i].equals(previousState[i])) {
                    isChange = true;
                }
                if (isChange) {
                        //check for status property of Employee
                        if(propertyName[i].equals("status")){
                        //Do your activity here - maybe you want to publish application event using eventService.       
                        //Define event. 
                            publisher.publishEvent(event);
                        }
                        report = false;
                    }           
            }       
            log.info("Exit onChange()...");
    }

To publish a custom ApplicationEvent, call the publishEvent() method on an ApplicationEventPublisher. For more details on event publishing, please check Section 5.14.2 Standard and Custom Events here.


Need Your Help

Sort point list into polygon

math polygon computational-geometry

I have a set of points. This set of points do define a (non convex) polygon but its not ordered.