GRAPH_WILL_FLUSH turned out to be insufficient where it was placed.
I think it only picks up changes committed to a parent context.
I ended up going with this instead inside the synchronized block of
flushToParent(). And since it wasn't really dealing with graph
flushing at this point, I renamed it to DataContextWillCommit.
### Eclipse Workspace Patch 1.0
#P cayenne-STABLE-3.0
Index:
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
===================================================================
---
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
(revision 1523007)
+++
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
(working copy)
@@ -1110,6 +1110,9 @@
synchronized (objectStore) {
ObjectStoreGraphDiff changes = objectStore.getChanges();
+
+ fireDataContextWillCommit(this, changes);
+
boolean noop = isValidatingObjectsOnCommit()
? changes.validateAndCheckNoop()
: changes.isNoop();
On Sat, Sep 14, 2013 at 10:35 AM, Mike Kienenberger <[email protected]> wrote:
> As I noted on the user mailing list, I haven't been able to find an
> equivalent of DataContext.WILL_COMMIT in 3.0.2.
>
> This change adds that functionality and all the unit tests continue to
> pass. Does anyone see a problem with it? Is there a better approach
> to take? Another approach I considered was to add a willCommit()
> method to DataContextDelegate.
>
> I haven't looked at 3.1 or 3.2 yet, but I'm going to guess that it
> will also work there. The performance hit should be minor, especially
> since there will be no default listeners.
>
> Note that the change to DataContext is to fire the event as the first
> action in protected GraphDiff onContextFlush() -- the method name was
> unfortunately truncated in the diff.
>
>
> ### Eclipse Workspace Patch 1.0
> #P cayenne-STABLE-3.0
> Index:
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> ===================================================================
> ---
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> (revision 1523007)
> +++
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
> (working copy)
> @@ -1069,6 +1069,8 @@
> GraphDiff changes,
> boolean cascade) {
>
> + fireDataChannelWillCommit(originatingContext, changes);
> +
> boolean childContext = this != originatingContext && changes != null;
>
> try {
> Index:
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannel.java
> ===================================================================
> ---
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannel.java
> (revision 1523007)
> +++
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataChannel.java
> (working copy)
> @@ -57,6 +57,10 @@
> public static final EventSubject GRAPH_CHANGED_SUBJECT =
> EventSubject.getSubject(
> DataChannel.class,
> "graphChanged");
> +
> + public static final EventSubject GRAPH_WILL_FLUSH_SUBJECT =
> EventSubject.getSubject(
> + DataChannel.class,
> + "graphWillFlush");
>
> public static final EventSubject GRAPH_FLUSHED_SUBJECT =
> EventSubject.getSubject(
> DataChannel.class,
> Index:
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> ===================================================================
> ---
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> (revision 1523007)
> +++
> framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
> (working copy)
> @@ -315,6 +315,18 @@
> boolean cascade);
>
> /**
> + * @since 3.0.2
> + */
> + protected void fireDataChannelWillCommit(Object postedBy,
> GraphDiff changes) {
> + EventManager manager = getEventManager();
> +
> + if (manager != null) {
> + GraphEvent e = new GraphEvent(this, postedBy, changes);
> + manager.postEvent(e, DataChannel.GRAPH_WILL_FLUSH_SUBJECT);
> + }
> + }
> +
> + /**
> * @since 1.2
> */
> protected void fireDataChannelCommitted(Object postedBy,
> GraphDiff changes) {
>
> On Sat, Sep 14, 2013 at 10:04 AM, Mike Kienenberger <[email protected]>
> wrote:
>> Further testing shows that GRAPH_FLUSHED_SUBJECT would be DID_COMMIT
>> not WILL_COMMIT.
>> So I'm still unable to get a single one-time notification before a
>> DataContext will commit a transaction.
>>
>> On Fri, Sep 13, 2013 at 2:39 PM, Mike Kienenberger <[email protected]>
>> wrote:
>>> So right after I sent my last message, I realized that while
>>> DataContext.WILL_COMMIT was gone, EventManager was still around.
>>>
>>> I did a quick search to see what kind of events were published, and I
>>> saw this one:
>>>
>>> DataChannel.GRAPH_FLUSHED_SUBJECT
>>>
>>> Is this equivalent to the DataContext.WILL_COMMIT event?
>>>
>>>
>>>
>>> On Fri, Sep 13, 2013 at 2:32 PM, Mike Kienenberger <[email protected]>
>>> wrote:
>>>> So I'm finally making the attempt to upgrade my ancient Cayenne
>>>> project from 1.1 to 3.x.
>>>>
>>>> The one kind of compile error I still haven't resolved is registering
>>>> for a data context commit.
>>>>
>>>> I know I can register individual PrePersist, PreRemove, and PreUpdate
>>>> callbacks for individual entity types, but I don't see how I be
>>>> notified of with a single DataContext.WILL_COMMIT event once before
>>>> each context.commit().
>>>>
>>>>
>>>> I see three problems with trying to use the individual callbacks:
>>>>
>>>> - Huge performance hit of being notified for each and every entity
>>>> committed
>>>>
>>>> - Another performance hit of setting up lifecycle notification by
>>>> iterating through the runtime metadata to register every existing
>>>> entity type for each of the three pre-commit listeners
>>>>
>>>> and
>>>>
>>>> - If nothing gets changed by the commit, then I would still get no
>>>> notification.