Listening for cache coordination [message #1426497] |
Thu, 18 September 2014 21:06 |
Ross Goldberg Messages: 7 Registered: July 2014 |
Junior Member |
|
|
I would like to somehow register a listener with EclipseLink 2.5.2 for whenever cache coordination messages have been received and processed by EclipseLink.
The listener would have to have a collection of coordinated entities passed in as an argument, so that my code could perform different logic depending on what entities were coordinated.
I've seen a few classes that might be of use, but I'm not sure how they work, or if there are other ways of achieving my goal.
FYI, I'm using JMS cache coordination, if that makes any difference.
Any help would be appreciated.
Thanks.
List of potentially useful classes:
org.eclipse.persistence.sessions.coordination.RemoteCommandManager
org.eclipse.persistence.internal.sessions.coordination.MetadataRefreshCommand
org.eclipse.persistence.sessions.coordination.MetadataRefreshListener
org.eclipse.persistence.sessions.interceptors.CacheInterceptor
org.eclipse.persistence.internal.sessions.coordination.jms.JMSTopicRemoteConnection
[Updated on: Thu, 18 September 2014 21:13] Report message to a moderator
|
|
|
|
Re: Listening for cache coordination [message #1427068 is a reply to message #1427038] |
Fri, 19 September 2014 16:57 |
Ross Goldberg Messages: 7 Registered: July 2014 |
Junior Member |
|
|
Chris,
Thanks for the info.
A few questions.
I don't want to interfere with the normal working of EclipseLink. I just want to have my code in the receiving servers know that certain data was updated, so that, if certain conditions are met, my code can perform certain business logic.
I'd like to do this at the EntityManagerFactory level, rather than at the EntityManager level.
Is there any reason to choose SessionEventListener over remote commands, or vice versa? (or any other option, if there are other options)
Since I want to use the newly updated data, for SessionEventListener, I assume that I should use:
postDistributedMergeUnitOfWorkChangeSet(SessionEvent event)
instead of:
preDistributedMergeUnitOfWorkChangeSet(SessionEvent event)
Is there documentation for SessionEvent, SessionEvent, etc. besides the JavaDocs? They're not too verbose.
In my postDistributed... listener method, will the EclipseLink caches have already been updated with the new values? Or must I call refresh on any entity that I want to use? (I assume the former)
Do I obtain the info about what data has changed from SessionEvent#getProperty(String). If so, are the property names and values documented anywhere? It looks like both getResult() & getQuery() will be null for postDistributed... and I can't see other methods that look like they'd provide coordination info.
will postDistributed... ever be called for anything other than a cache coordination?
I assume that I can leave all the other methods in my SessionEventListener as no-ops.
Thanks again,
Ross
|
|
|
Re: Listening for cache coordination [message #1432091 is a reply to message #1427068] |
Fri, 26 September 2014 15:50 |
Chris Delahunt Messages: 1389 Registered: July 2009 |
Senior Member |
|
|
Docs - I remember there being good docs, but my links keep changing, so I don't know of any off hand. I'll try searching later, but I mostly just use the source code for reference.
First, The EntityManagerFactory in JPA is essentially treated as a wrapper on EclipseLInk's session, while the EntityManager is considered a wrapper on the UnitOfWork (a special session). If you are following the native EclipseLink ORM docs, its a 3 tier architecture. So your session event listeners would almost always be registered in the shared ServerSession/EMF rather than the UOW/EntityManager, especially these, since an EM/UnitofWork is never used as a listener for cache coordination.
Yes, the pre/postDistributedMergeUnitOfWorkChangeSet() event is only triggered from cache coordination's MergeChangeSetCommands, so no other EclipseLink api will trigger this event, and it gets fired in a finally block after merging the changeset into the session. The SessionEvent sent to the listener is built in the SessionEventManager's postDistributedMergeUnitOfWorkChangeSet method:
SessionEvent event = new SessionEvent(SessionEvent.PostDistributedMergeUnitOfWorkChangeSet, getSession());
event.setProperty("UnitOfWorkChangeSet", changeSet);
So event.getProperty("UnitOfWorkChangeSet") will give you a UnitOfWorkChangeSet instance that contains the delta's mentioned before. Check the MergeManager's mergeChangesFromChangeSet method if you need an example of how it is used.
As for caches being refreshed - which caches is important. The event itself has access to the shared Session object, which will have the changes. Outside UOW/EntityManagers might not - they operate like transactions and maintain their own caches. Any new UOW/EM or one that is cleared will pick up the changes (I only mentioned this because a common app design problem is to reuse long lived EntityManagers rather than obtain them as needed)
You might want to have your SessionEventListener extend the SessionEventAdapter class, and then just override the postDistributedMergeUnitOfWorkChangeSet method.
The issue with using a Session event listener might be that it only lives while the session lives, and postDistributedMergeUnitOfWorkChangeSet is only called for remote changes. Local changes fire postMergeUnitOfWorkChangeSet events) So if (for some reason) all your EntityManagerFactories are closed and garbage collected, your listener will not receive messages from remote servers. If you want it independent of the EntityManagerFactory's lifecycle, and get all RemoteCommand change events (even the ones from your local EMF), you might register your own JMS listener rather than use an event listener. Just mentioning it because you haven't mentioned what you are using it for.
Best Regards,
Chris
|
|
|
Powered by
FUDForum. Page generated in 0.03190 seconds