Re: How to selectively save EO
Re: How to selectively save EO
- Subject: Re: How to selectively save EO
- From: Chuck Hill <email@hidden>
- Date: Mon, 24 Apr 2006 10:27:13 -0700
Hi Louis,
I'd like to try an add some clarification to the issue(s) being
discussed. I think there are a couple of overlapping areas that
could benefit from some more examination.
One of the central responsibilities of EOF is to ensure object graph
consistency. There are three views of this object graph that need to
be considered:
1) All objects, as represented in the persistent store, usually a
relational database
2) The subset of (1), the objects represented in EOF's snapshots
3) The subset of (2), the objects in a single editing context
There is only ever a single version of (1). In terms of uniqueness,
existence, etc. the database has the final say.
There will be a version of (2) for each EOF stack, which in practice
usually means for each running application instance. Synchronization
between these versions is largely left up to the developer, using
refreshing fetches, expiring snapshots, setting snapshot age limits
on editing contexts, and using one of the versions of the
distributed change notification framework. EOF's role in this area
is restricted to throwing exceptions, for example when the out of
date data in a snapshot causes an optimistic locking failure.
There will be a version of (3) for each EOEditingContext. As long as
the editing context has not been saved, EOF allows these versions to
remain separate. When a particular editing context is saved, EOF
steps in and updates (1), (2) for the EOF stack that the editing
context is in, and (3) for all the other editing contexts in that EOF
stack.
What people are saying is that it is wrong to try and save _part_ of
a version (3). Doing this would be analogous to a database saving
only some of the rows in a transaction, or to a developer making a
cvs commit of only some of the files they changed to fix a bug. The
result would be inconsistent, incorrect, and useless.
It is perfectly permissible, and in fact nearly unavoidable, to have
multiple, differing versions of (3) and to save any, all, or none of
them. EOF will synchronize the saved changes with the other editing
contexts upon save.
Now lets look at some specifics.
On Apr 23, 2006, at 4:03 PM, Louis Demers wrote:
At 3:22 PM -0400 2006/04/21, Paul Suh wrote:
Louis,
Trying to save a single EO while leaving others unsaved is almost
always indicative of a problem in your application's design....
That was my initial concern and the reason I asked the question on
how to do it, knowing I would be corrected by this list if that was
a NONO 8-), I was worried that my design was flawed because it
motivated me to do this.
Your motivation was correct, it was your intended implementation that
was flawed.
My application is some sort of ERP for our particular needs, and I
wanted to record some signature that someone was trying to edit
some objects.
The object I wanted to save was a signature object referring to an
object that already existed in the database but that may have been
edited without being committed yet. The object being saved is not
at the discretion of the user but my own requirement to keep track
of what is being done. I could restrain the user to a very strict
paradigm, but knowing the crowd I'm trying to please, I'd rather not.
What you have then is two versions of the object graph. In the first
version, a user is editing an object. They may or may not save this
version. In the second version of the object graph, a signature
object has been created and referrers to a previously saved object
that just happens to be in the other version. This second version
will be saved regardless of what the user editing the first version
does. This is normal function within EOF.
What would be wrong is if the user was creating an object, rather
than editing one, in the first version and you tried to save a
signature referring to it in the second version. This would not work
at the database layer either, as you would have a foreign key
referring to a non-existent row in another table. Neither EOF nor
relational databases allow this sort of inconsistent data.
Your comments echoed some feelings I had when I faced this
technical difficulty and a re-examination of the task has me fairly
well convinced that what I want to do is legitimate.
It is perfectly legitimate.
Whether WebObjects has the flexibility is something else, but the
solutions proposed so far , in particular
"EOtilities.localInstanceOfObject" support the idea that WebObjects
has foreseen this requirement. I do realize this special steps
forces me to investigate my model/paradigm and I will have to take
the responsibility to make sure I do not just push forward a
problem in my model design.
Yes, localInstanceOfObject and a peer editing context (a new (3)
version) are what you need. The defaultEditingContext() in WOSession
is a convenience, nothing more. It is just a _default_ version for
easy access. Creating more versions is almost always the right thing
to do. Personally, I avoid ever editing in the default, and always
create a new version (aka peer editing context) whenever data will be
changed (created, updated, deleted). This allows you to keep
multiple actions from the same user from interacting with each other
in undesired ways.
Please note, that when you start to create alternate versions (again,
peer editing contexts), _you_ are responsible for locking and
unlocking them so that EOF can do its synchronization work at the
correct time. Locking and unlocking at the correct time is complex
and error prone. I strongly suggest that you use a known working
solution such as the MultiECLockManager:
http://wocode.com/cgi-bin/WebObjects/WOCode.woa/2/wa/ShareCodeItem?
itemId=301
You will also find a discussion of locking and object graph handling
in my Practical WebObjects book if you want to dive in deeper.
I taught this was a newbie question , but the discussions it raised
have been most enlightening.
It is a question that touches on many important aspects of EOF.
I implemented the solution based on
EOUtilities.localInstanceOfObject after reviewing some "Use Cases"
to evaluate the potential impacts, and I'm convinced the need is
legitimate and the solution reliable. What more can I ask. On to
the next feature.
Chuck
--
Coming in late 2006 - an introduction to web applications using
WebObjects and Xcode http://www.global-village.net/wointro
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