Re: Unexpected awakeFromInsertion() behaviour
Re: Unexpected awakeFromInsertion() behaviour
- Subject: Re: Unexpected awakeFromInsertion() behaviour
- From: Chuck Hill <email@hidden>
- Date: Thu, 10 Jan 2008 11:04:01 -0800
That looks like a bug, the EC should either not be calling
awakeFromInsertion() or should be seeing the notifications from the
change in value. It makes sense to me for it to call
awakeFromInsertion() *BUT* this results in an object state different
from what was there before the changes being reverted. That seems to
be a very wrong result.
You will often see the method written as:
// in Order.java
public void awakeFromInsertion(EOEditingContext ec) {
super.awakeFromInsertion(ec);
if (statusMessage() == null) {
setStatusMessage("incomplete");
}
}
I don't do that myself (I probably should!), but I expect this is
done to handle the situation you are seeing.
Chuck
On Jan 9, 2008, at 3:37 PM, Peter Vandoros wrote:
Hi Chuck,
Chuck Hill wrote:
Hi Peter,
On Jan 9, 2008, at 2:49 PM, Peter Vandoros wrote:
Chuck Hill wrote:
On Jan 8, 2008, at 9:23 PM, Peter Vandoros wrote:
I came across an interesting behaviour today with
awakeFromInsertion() that i did not expect and I hope someone
could shed some light.
What happens is that awakeFromInsertion() is not only called
when the EO is "created" but also when reverting the editing
context after having deleted an EO (which hasn't yet been
saved). That is, if you delete an EO and revert() instead of
saveChanges(), that EO's awakeFromInsertion() method is called
again.
The documentation states:
"Overridden by subclasses to perform additional initialization
on the receiver upon its being inserted into ec. This is
commonly used to assign default values or record the time of
insertion. ...."
I originally took this to mean that it is only called when the
EO is _created_. Technically speaking, the documentation states
that it is called when the EO is _inserted_ into the editing
context which does not necessarily mean when the EO is _created_.
Does this mean that I need to go through all my EO's that use
this method for some initialisation and take this scenario into
account or is this a bug with WO?
I am using WO 5.2.4.
Is this what you are talking about?
com.webobjects.eocontrol.EOEditingContext ec = newEditingContext();
ec.lock();
Order o = new Order();
ec.insertObject(o);
ec.deleteObject(o);
ec.revert();
ec.unlock();
I log a stack trace from Order.awakeFromInsertion. I do not get
a call to awakeFromInsertion when the ec is reverted in WO 5.3.3.
Log out a stack trace from awakeFromInsertion and see what it
says for the second call:
public void awakeFromInsertion(EOEditingContext ec)
{
NSLog.out.appendln(new RuntimeException("backtrace"));
super.awakeFromInsertion(ec);
. . .
I'd be interested to see it.
That is not exactly what i am talking about.
The code below demonstrates what i am talking about.
EOEditingContext ec = new EOEditingContext();
ec.lock();
try {
Order order = (Order) EOUtilities.createAndInsertInstance
( ec, "Order" );
// set order properties so it can be saved successfully
ec.saveChanges();
ec.deleteObject( order);
NSLog.out.appendln("should see awakeFromInsertion call now...");
ec.revert();
NSLog.out.appendln("did you see the awakeFromInsertion call?");
}
catch (Exception e) {
System.err.println("Error with test");
e.printStackTrace();
}
finally {
ec.unlock();
}
The stack trace (the interesting part) that i get when this
happens is:
java.lang.RuntimeException: backtrace
at com.etechgroup.test.eo.Order.awakeFromInsertion(Order.java:
44)
at
com.webobjects.eocontrol.EOEditingContext.insertObjectWithGlobalID
(EOEditingContext.java:2851)
at com.webobjects.eocontrol.EOEditingContext.insertObject
(EOEditingContext.java:2871)
at com.webobjects.eocontrol.EOEditingContext.revert
(EOEditingContext.java:4570)
It looks as though the editing context re-inserts a deleted EO if
that EO is not newly created and you revert.
Of course it does! deleteObject makes the object not exist.
Reverting that makes it exist again. So it is newly created and
get awoken again. Revert is more like undo than "forget what I
just changed".
ec.deleteObject(order);
ec.saveChanges();
ec.undo();
ec.saveChanges();
I am not sure of the exact calls, but it is possible to reverse
changes committed to the database. Or it was at one time, I have
seen this happen due to a bug processing delete rules. Much fun
debugging that one.
I can imagine :-)
I'm glad i cleared this up and gave other people on this list a
heads up about this behaviour. At least now I know about this and
have worked around it by creating a new method in my generic record
super class awakeFromCreate() which is called by awakeFromInsertion
() only if the EO is newly created. This way, it does what i
thought awakeFromInsertion() does and what i was using it for.
On a side note, i also noticed that if the default values that are
set in awakeFromInsertion() differ from the committed value, EOF
does not pick up that change leaving that EO/EditingContext in an
invalid state. This is actually what bit me yesterday and lead me
to investigate this behaviour.
This one _may_ be a bug. I can report it if you think it is a bug.
For example:
// in Order.java
public void awakeFromInsertion(EOEditingContext ec) {
super.awakeFromInsertion(ec);
setStatusMessage("incomplete");
}
// in SomeTestFile.java
EOEditingContext ec = new EOEditingContext();
ec.lock();
try {
Order order = (Order) EOUtilities.createAndInsertInstance( ec,
"Order" );
order.setStatusMessage("complete");
ec.saveChanges();
ec.deleteObject( order );
System.out.println("should see awakeFromInsertion call now...");
ec.revert();
System.out.println("did you see the awakeFromInsertion call?");
// the stateMessage should be 'complete' but you will see that
it is 'incomplete'
NSLog.out.appendln("order.statusMessage should be 'complete',
but it is: " + order.statusMessage());
// the editing context also does not show any changes
NSLog.out.appendln("ec.hasChanges: " + ec.hasChanges());
NSLog.out.appendln("ec.insertedObjects: " + ec.insertedObjects
().count());
NSLog.out.appendln("ec.updatedObjects: " + ec.updatedObjects
().count());
NSLog.out.appendln("ec.deletedObjects: " + ec.deletedObjects
().count());
}
catch (Exception e) {
System.err.println("Error with test");
e.printStackTrace();
}
finally {
ec.unlock();
}
As always Chuck, your help is much appreciated.
Thanks
--
Peter Vandoros
Software Engineer
Etech Group Pty Ltd
Level 3/21 Victoria St
Melbourne VIC 3000
Australia
Ph: +61 3 9639 9677
Fax: +61 3 9639 9577
----------------------------------
IMPORTANT: This e-mail message and any attachments are confidential
and may be privileged. If received in error, please reply to this
message and destroy all copies and any attachments. You should
check this message and any attachments for viruses or defects. Our
liability is limited to resupplying any affected message or
attachments. For more information about Etech Group, please visit
us at http://www.etechgroup.com.au.
--
Practical WebObjects - for developers who want to increase their
overall knowledge of WebObjects or who are trying to solve specific
problems.
http://www.global-village.net/products/practical_webobjects
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden