We have a scenario, where we need a call back method when any updates made to entity are committed to Database.
Methods marked @postupdate are called back on transaction commit and on em.flush().
Since executing a Query with FlushType=AUTO triggers a em.flush() the @postUpdate method is called back when such a query is executed.
Since the transaction may be rolled back after a em.flush() annotating method @postUpdate is not sufficient when we want certain piece of code to be executed when changes are committed.
I did explore registering SessionEventListener with Toplink. There are couple of problems with this too.
1. postCommitTransaction() is called when an entity is persisted
2.Since SessionEvent does not contain the entity that is committed this event listener also does not offer any solution.
Tried postCommitUnitOfWork(). It gets called only on commit. In this callback method i want to verify if the entity, which is committed is my required entity or not?
If it matches with the required entity , I want to execute a method here.
But how do I get committed entity in postCommitUnitOfWork?
I've seen getAllClones() in UnitOfWorkImpl. Can i get this hashtable in the call back method??
Please let me know how to achieve this.
Edited by: user556430 on Feb 4, 2013 1:58 PM
Try using a pre/postMergeUnitOfWorkChangeSet event, and look up the 'UnitOfWorkChangeSet' property to get the changeset from the event. If you are going to use the postCommitUnitOfWork, the session in the event is the UnitOfWork, which you can use to call getUnitOfWorkChangeSet() or getAllClones if you wish.
The changesets will contain all the changes made in the transaction.
I'm using postCommitUnitOfWork(). From the event when I'm trying ot get unitofwork, i'm always getting null.
Here is what I'm doing :
added this entry to persistence.xml
<property name="toplink.session.customizer" value="jpa.tests.MySessionCustomizer"/>
customize() method in MySessionCustomizer is:
public void customize(Session session) throws Exception
PostCommitEventListener listener = new PostCommitEventListener();
And overriden method in PostCommitEventListener is:
public void postCommitUnitOfWork(SessionEvent event)
Session session = event.getSession();
UnitOfWork acquireUnitOfWork = session.getActiveUnitOfWork();
UnitOfWorkChangeSet unitOfWorkChangeSet = acquireUnitOfWork.getUnitOfWorkChangeSet();
IdentityHashtable allChangeSets = unitOfWorkChangeSet.getAllChangeSets();
Enumeration enumeration = allChangeSets.elements();
System.out.println("enumeration has more elements: " + enumeration.hasMoreElements());
When I've debugged, I've got this exception.
Nested units of work are not supported in TopLink Essentials
How do I get committed entity from SessionEvent in PostCommitUnitOfWork()?
The session you are getting from the event using event.getSession() is the UnitOfWork, which is why you get an exception when you then try to call getActiveUnitOfWork on it - you are getting a UOW from a UOW which is not supported. Cast the session to a UnitOfWork to call getAllChangeSets on it.