Wednesday, May 22, 2013

Intercept your JPA (OpenJPA) calls with Entity Listeners


This is a quite a simple thing to achieve, but also quite useful.

1. You can configure listeners  per entity. Can have multiple callbacks for one entity.
2. Register a default listener which will intercept call JPA calls.


There are callback methods supported by JPA as follows. Refer [1] for more info.

  •  PrePersist: Methods marked with this annotation will be invoked before an object is persisted. 
  •  PostPersist: Methods marked with this annotation will be invoked after an object has transitioned to the persistent state.
  •  PostLoad: Methods marked with this annotation will be invoked after all eagerly fetched fields of your class have been loaded from the datastore. No other persistent fields can be accessed in this method. 
  •  PreUpdate: Methods marked with this annotation will be invoked just the persistent values in your objects are flushed to the datastore. 
  •  PostUpdate: Methods marked with this annotation will be invoked after changes to a given instance have been stored to the datastore. 
  •  PreRemove: Methods marked with this annotation will be invoked before an object transactions to the deleted state. Access to persistent fields is valid within this method. 
  •  PostRemove: Methods marked with this annotation will be invoked after an object has been marked as to be deleted. This is equivalent to the XML element tag post-remove.

So in your Entity class you can have a annotation as follows and register multiple listener classes.

@EntityListeners({ MyListenerOne.class, ... })

And once those are defined as above, in OpenJPA,  there is this configuration file  
META-INF/persistence.xml  in your class path. There you define the Persistence provider and etc. 
Meanwhile you can provide a pointer to a  mapping file which has the details of the entity listeners and for what callbacks these listeners should listen.

That is META-INF/orm.xml. So the orm.xml file is the file that you should define the mapping of the entity listeners and callback methods.

i.e in orm you can add following.

    
        
        
        addData
        removeData
        
    
So as you expected, the listener class "MyListener" should be as follows.
    public class MagazineLogger {

            @PostPersist
            public void logAddition(Object pc) {
            //
            }

            @PreRemove
            public void logDeletion(Object pc) {
            //
            }
            }
If you want to register a default listener that listen to all JPA calls, your orm.xml should add following 
    
        
            
                
                    
                        
                            
                            
                        
                    
                
            
        
    
Download OpenJPA runtime and try your self. ;-)

No comments:

Post a Comment