Are other people using nested editing contexts?
Yes, in reasonably heavily used production applications. BUT the
big difference that I see is that you seem to create on per
session. I usually create one per function/page.
This seemed like the way to go to me, too, at first. But then I read
(see link below) that you couldn't reliably lock an editing context
in a page's awake/sleep like in session, because those might not
always get called with a one to one correlation (that is, you might
somehow have two awake() invocations or two sleep() invocations in a
row). Since attributes on EOs in that ec will be getting set when
the form values are pulled, I didn't know how to lock correctly if I
couldn't lock/unlock in awake/sleep, so I moved all that business to
session, as the post suggested.
from http://en.wikibooks.org/wiki/Programming:WebObjects/EOF/
Using_EOF/Context_and_Database_Locking:
"In general you are better to lock EC's in the session (if you've got
one) rather than the component"
and
"One thing to watch out for is that EC locking on the page's awake()
and sleep() doesn't really work, because awake may be called more
often than sleep."
So how do you get around the locking issues at the page level? Do
you just use the project wonder classes, which appear to lock
everything for you?
I finally found a workaround that works, taken from a post in like
2002. In Application's constructor, I call
EODatabase.disableSnapshotRefCounting();
HACK! :-)
Agreed :) But why does it work? If the application runs great
without snapshot reference counting, it tells me that the problem
lies in the way EODatabase is managing its snapshot dictionary.
Specifically in this instance, it seems to be decrementing the count
of things pointing to each entry prematurely, leading it to
prematurely delete the dictionary entry. So what are the possible
causes of EOF making this mistake (or what is it that I'm doing that
prompts EOF to make this mistake, if you prefer ;))? I guess that's
what this whole thread has been about. Here's the list of things I
know about:
Don't set EO properties in the EO constructor -- use
awakeFromInsertion(...) or awakeFromFetch(...) instead : I've
examined each and every EO constructor in all my frameworks at least
4 times now. Most either don't exist, or just call super(), and the
rest (one or two) only call super() and set a couple of non-modeled
local attributes.
Don't do anything to an EO before inserting it into an editing
context. Always insert EOs into ECs immediately. See rule #1: I made
a comprehensive list of all my EO classes (about 90) and then
searched all applications and frameworks for "new X()" where X is
the name of each EO. There are no results for any of my EOs anymore,
because they all use EOUtilities.createAndInsertInstance. There are
actually one or two places that I use introspection to create new
EOs ,but in each of those places, they get inserted immediately after
creation. Actually, this is something I've never heard discussed.
Does EOF play nice with introspection? Maybe that is my problem. I
will rewrite that code next...
Don't modify any EO properties in validateFor...(...) methods. Doing
this in validateValueForKey(...) is ok as Chuck Hill noted in the
list.: There is only one validateFor method in all of the frameworks
and applications:
public void validateForSave() throws
NSValidation.ValidationException {
super.validateForSave();
if ( supplier() == null ) {
throw new NSValidation.ValidationException( "All inventory
items must have a supplier" );
}
}
If over-riding awakeFromInsertion(...), remember to call ther
superclass implementation. Same with awakeFromFetch(...): This was
the easiest one to verify. Searched all EOs, and for sure they all
call super.awake...
Don't change the behavior of methods that EOF uses. For example, do
not override to-many relationships to return a sorted list of the
related objects. Make another method to do this.: Verified that this
cannot happen by commenting out all overridden methods in every EO I
have, recompiling, rerunning the problematic code, and getting the
same behavior
Don't use mutable classes (e.g. NSMutableArray, NSMutableDictionary,
any other class that can change internal state after creation) as
attributes. If you want this effect, use immutable classes and
provide cover methods to replace the immutable instance with an
updated instance. You and EOF will be much, much, much happier:
Definitely not doing this
Locking problems: I turned on DebugGroupMultithreading in NSLog, and
nothing happened. If I explicity comment out the code which locks my
ECs, I get warnings all over the place, so it looks like my code is
working in that regard.
Does anyone know of any other thing that causes EOF's snapshot
counting to go screwy?
You have something seriously bad in your application. I don't know
what it is, yet. But there is something you are not telling us
(not accusing you here, you undoubtedly are dismissing it as not
relevant, I know that from personal experience). In my experience,
EOF is very robust and dependable. As long as you don't mess with
its head...
Well, I guess I can't complain too much. After all, they aren't
charging anything for the product any more. And as long as there are
good people willing to fill in the information gaps left by Apple
about the product by sharing their experiences, I think it can
continue to be a great way to develop web applications. For now, I'm
going with the hack because I don't know what else to do. Thanks to
all who continue to respond, and by all means, if anyone can think of
anything else to try or anywhere else to look, let me know and I will
try it/look there.
Mark
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (Webobjects-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [EMAIL PROTECTED]