Re: Child Parent Editing Context
Re: Child Parent Editing Context
- Subject: Re: Child Parent Editing Context
- From: Chuck Hill <email@hidden>
- Date: Mon, 19 Sep 2005 10:00:55 -0700
Thanks Jerry. I was running out of steam when I replied and fudged
the last bit. Thanks for the illuminating reply. I've taken the
time to put this in our very slowly growing FAQ:
http://www.gvcsitemaker.com/gvc.webobjects/
faq&mode=single&recordID=38383&nextMode=list
Chuck
On Sep 17, 2005, at 6:23 AM, Jerry W. Walker wrote:
Hi, Owen,
Everything Chuck said in his last message is true (and clearer than
you will hear it from most other sources), but to add just one more
clarification (wrinkle) to the answer... Chuck said in his last
sentence, "When one of these objects changes and then gets saved,
this updates the snapshot and all the other versions can see the
updated data as well."
While this is true, note that the phrase "... can see the updated
data as well." is distinct from the phrase "...will see the updated
data as well." In particular, they won't see any changes in
attributes that they have also just changed. This is why he said,
"Only when changes are made do they hold data, and just the changed
data."
In particular, say you updated a Person EO for Sally Smith in your
editing context by changing only her lastName attribute to "Jones"
without savingChanges. Say someone else in another editing context
also updated Sally Smith's lastName attribute to "Brown" but also
updated her age from 26 to 27 and savedChanges on his editing context.
If you then took another look at your Sally Smith EO. You would see
that her age had changed (from 26 to 27) since you hadn't touched
the age attribute, but you would still see that her lastName was
"Jones" as you had last set it, because the lastName attribute of
your Sally Smith nee Jones nee Brown EO no longer references the
lastName attribute in the snapshot but rather references the local
String that you provided to change it.
Further, if you had marked the Locking characteristic for the
lastName attribute of Person in your EOModel, then when you tried
to save changes, EOF would throw an exception indicating that it
couldn't update the record. Though it's seldom obvious to the
newcomer, this is an optimistic locking exception and says that
someone changed the EO under you (that is, after you read it and
before you updated it).
Although everything I just said is implied by what Chuck said, it
is often confusing.
Hope this helps more than it confuses further.
Regards,
Jerry
On Sep 16, 2005, at 12:23 AM, Chuck Hill wrote:
On Sep 15, 2005, at 9:06 PM, Owen McKerrow wrote:
Nope that clears it up.
I still have trouble getting all those objects right. i.e. that
there is only one instance of a Object from the database per
EODatastore, but each Editing-Context for that datastore has its
own version of the object. Is that the case ?
It is a little hard to grasp. There is only one conceptual
object. There is only one object in the Object Store (aka
EODatabase). And there is absolutely only a single row in the
database (well, ignoring Vertical inheritance but let's not drag
that in). Except that it is not really an object as it has only
data and no behavior. You will usually hear this referred to as
the "snapshot".
Here comes the confusing part. To actually do something useful
with one of these alleged objects, you need to instantiate it as
an EOEnterpriseObject ( aka EOGenericRecord, EOCustomObject, or
subclass). These aren't really the object either. They are more
like a Facade. They have the missing behavior, but lack the
data. While they _appear_ to have the data, they actually only
have references to the data in the snapshot. These
EOEnterpriseObjects must live in an EOEditingContext. There can
be many of them (one for each EC), but they all reference the same
data in the snapshot. Only when changes are made do they hold
data, and just the changed data. When one of these objects change
and then get saved, this updates the snapshot and all the other
versions can see the updated data as well.
Chuck
On 16/09/2005, at 1:42 PM, Chuck Hill wrote:
On Sep 15, 2005, at 8:34 PM, Owen McKerrow wrote:
See below.....
On 16/09/2005, at 4:05 AM, Chuck Hill wrote:
On Sep 14, 2005, at 3:35 PM, Owen McKerrow wrote:
Hi All,
Sorry I forgot to mention where externalDetails() comes from.
External has a one to one with externalDetails and propagates
its primary key to it. Now my understanding is that if you
have a one to one which propagates its primary key when you
make an instance of one of the objects EOF makes the other
one for you, in this case I make my External object, EOF
realizes that it will need an external details so it creates
one.
No, that is not correct as Auturo has pointed out.
Once again my understanding is that it would use the same
editing context as the External Object itself. Do I need to
explicitly register this "auto created" object with the
EditingContext ? I would have though not, as I was even
printing out the editing context of both objects, external
and externalDetails, and they had the same editing context.
it sounds to me like the list on the first page is showing a
list of items in defaultEditingContext() and one in
childEditingContext.
When going back to the first page, you need to use
EOUtilities.localnstanceOfObject(defaultEditingContext(),
addedEO) to get an EO that you can add to the list.
Thats exactly it. What I was wondering is if I have registered
my second editing context as a child of the default one, create
my objects in this new editing context, commit its changes,
should it not pass these changes back up to its parent ? Or
does that not include passing the new object back up but only
changes to objects which already exist in the parent ?
Yes, but. The changes _do_ get pased back up to the parent, but
they are not the same object. Each EO instance lives in one and
only one editing context. So the new object in
defaultEditingContext() will have the same values and same
global ID as the object in childEditingContext. BUT and this is
a big BUT it is NOT the same Java object. That is, the objects
are equivalent but not ==. They are the same conceptual object
but not the same physical object.
Is that making any sense, or I am just rambling?
Chuck
On 14/09/2005, at 6:31 PM, Wolfram Stebel wrote:
Am 14.09.2005 8:40 Uhr schrieb "Owen McKerrow" unter
<email@hidden>:
Hi All,
Hi too,
normaly this error comes, when one of the associated objects
is not in the
same ec, so this seems to me, that in
try {
createdPerson.externalDetails().validateForSave
();
} catch (NSValidation.ValidationException
exception) {
validationDic.setObjectForKey
(Boolean.TRUE,"saveValidationFailed");
validationDic.setObjectForKey
(exception.getMessage
(),"saveValidationString");
}
there is externalDetails().validateForSave(), where
externalDetails() seems
to be another object...
Do you use any setters assigning other objects actually not
shown in your
initatenewExternalPerson?
Wolfram
This is a question that comes from my lack of understanding
how a
parent child editing context works. Well I think thats the
cause :)
I have a page which allows some to add a new external
member to the
site if they aren't already listed. So they click the "Add new
external member button." I create a new member in a child
editing
context of the current editing context ( so if they cancel
I can just
forget about it), they fill in the details and hit the save
button, I
then return them to the page they were one and the new
person now
becomes available to be selected from the pop-up list of
external
members.
The code for making a new person :
public void initatenewExternalPerson()
{
EOEditingContext editCon = new EOEditingContext
(ec); //Where
ec is the default editing context
createdPerson = (External)
EOUtilities.createAndInsertInstance
(editCon,"External");
PersonName newName = (PersonName)
EOUtilities.createAndInsertInstance(editCon,"PersonName");
createdPerson
().addObjectToBothSidesOfRelationshipWithKey
(newName,"personNames");
checkingExternalExists = false;
}
The code for the save :
public WOComponent saveNewExternalPerson()
{
//Probably some over kill here on all the validation
stuff but I
wanted to make sure this wasn't the problem.
try {
createdPerson.validateForSave();
} catch (NSValidation.ValidationException
exception) {
validationDic.setObjectForKey
(Boolean.TRUE,"saveValidationFailed");
validationDic.setObjectForKey
(exception.getMessage
(),"saveValidationString");
}
try {
createdPerson.externalDetails().validateForSave
();
} catch (NSValidation.ValidationException
exception) {
validationDic.setObjectForKey
(Boolean.TRUE,"saveValidationFailed");
validationDic.setObjectForKey
(exception.getMessage
(),"saveValidationString");
}
try {
createdPerson.activeName().validateForSave();
} catch (NSValidation.ValidationException
exception) {
validationDic.setObjectForKey
(Boolean.TRUE,"saveValidationFailed");
validationDic.setObjectForKey
(exception.getMessage
(),"saveValidationString");
}
if ( validationDic.count() == 0 ) {
createdPerson.editingContext().saveChanges();
}
return context().page();
}
Which must be working as the person appears in the pop-up
list as I
wanted them to, but as its only a child editing context it
only
registers the object with eparent it doesn't save these
changes to
the database ( at least thats my understanding after
reading Chucks
book ).
However when I then click on the main save button, I get the
following error :
Error:
java.lang.IllegalStateException: Cannot obtain globalId for
an object
which is registered in an other than the databaseContext's
active
editingContext, object: {values = {accessLevel = -1;
filePath = ;
onPayroll = 0; publications = (); staffNumber = ;
brandNewRecord = 0;
publicationsEditorOf = (); jchiefGrants = (); toBeShown =
1; title
= ; groupsCoOrdinates = (); email = ; jotherGrants = ();
academicGeneral = ; fileName = ; publicationsAuthorOf = ();
url = ;
personNames = (">"); groupMembers = (); hasFile = 0;
externalDetails
= ">"; institution = ; type = 4; }; this = ">"; },
databaseContext:
com.webobjects.eoaccess.EODatabaseContext@487471, object's
editingContext:
com.webobjects.eocontrol.EOEditingContext@ecea5e,
databaseContext's active editingContext:
com.webobjects.eocontrol.EOEditingContext@f46941
Reason:
Cannot obtain globalId for an object which is registered in
an other
than the databaseContext's active editingContext, object:
{values =
{accessLevel = -1; filePath =
<com.webobjects.foundation.NSKeyValueCoding$Null>;
onPayroll = 0;
publications = (); staffNumber =
<com.webobjects.foundation.NSKeyValueCoding$Null>;
brandNewRecord =
0; publicationsEditorOf = (); jchiefGrants = (); toBeShown
= 1; title
= <com.webobjects.foundation.NSKeyValueCoding$Null>;
groupsCoOrdinates = (); email =
<com.webobjects.foundation.NSKeyValueCoding$Null>;
jotherGrants = ();
academicGeneral =
<com.webobjects.foundation.NSKeyValueCoding$Null>;
fileName = <com.webobjects.foundation.NSKeyValueCoding$Null>;
publicationsAuthorOf = (); url =
<com.webobjects.foundation.NSKeyValueCoding$Null>;
personNames =
("<PersonName dd08eb <EOTemporaryGlobalID: 0 0 -126 -126 72
73 0 0 -6
79 3 0 0 0 1 6 83 75 92 -121 13 -113 120 -104>>");
groupMembers = ();
hasFile = 0; externalDetails = "<ExternalDetails 8c53f9
<EOTemporaryGlobalID: 0 0 -126 -126 72 73 0 0 -6 79 2 0 0 0
1 6 83 75
92 -121 13 -113 120 -104>>"; institution =
<com.webobjects.foundation.NSKeyValueCoding$Null>; type =
4; }; this
= "<External cb03c4 <EOTemporaryGlobalID: 0 0 -126 -126 72
73 0 0 -6
79 1 0 0 0 1 6 83 75 92 -121 13 -113 120 -104>>"; },
databaseContext:
com.webobjects.eoaccess.EODatabaseContext@487471, object's
editingContext:
com.webobjects.eocontrol.EOEditingContext@ecea5e,
databaseContext's active editingContext:
com.webobjects.eocontrol.EOEditingContext@f46941
So its saying that it can't save my new person object as its
registered in another editing context. Which I guess is
true it was
created in the child context, but I would have thought this
would
have worked, so that is I had saved the child editing
context which
then passes its changes up to the parent, save the parent,
passes the
changes onto the DB. But this doesn't seem to be the case.
Have I done something wrong or is my understanding flawed.
Thanks Very Much
Owen McKerrow
WebMaster, emlab
http://emlab.uow.edu.au
--
__ Jerry W. Walker, Partner
C o d e F a b, LLC - "High Performance Industrial Strength
Internet Enabled Systems"
email@hidden
212 465 8484 X-102 office
212 465 9178 fax
--
__ Jerry W. Walker, Partner
C o d e F a b, LLC - "High Performance Industrial Strength
Internet Enabled Systems"
email@hidden
212 465 8484 X-102 office
212 465 9178 fax
--
__ Jerry W. Walker, Partner
C o d e F a b, LLC - "High Performance Industrial Strength
Internet Enabled Systems"
email@hidden
212 465 8484 X-102 office
212 465 9178 fax
--
Unnamed - 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