Re: Creating new EOObjectStoreCoordinator for thread
Re: Creating new EOObjectStoreCoordinator for thread
- Subject: Re: Creating new EOObjectStoreCoordinator for thread
- From: Jeff Schmitz <email@hidden>
- Date: Wed, 06 Aug 2008 04:19:51 -0500
Actually, I was using:
EOObjectStoreCoordinator parentObjectStore = new
EOObjectStoreCoordinator();
EOEditingContext threadEditingContext = new
EOEditingContext(parentObjectStore);
and with that, I still was getting the error until I removed a
couple of the inverse relationships. Note that I didn't have to
remove them all of them, just a couple of them. Not sure what made
those cause trouble.
On Aug 5, 2008, at 11:21 PM, Chuck Hill wrote:
On Aug 5, 2008, at 9:05 PM, Jeff Schmitz wrote:
I fixed the problem by removing a couple of inverse relationships,
and I also needed to use ERXEC.newEditingContext(parentObjectStore)
to create my new editing context (instead of just new
EOEditingContext), and now it works. Since I wasn't using these
inverse relationships anyway it's no big deal, but I'm still not
sure what the root cause of the problem was.
new EOEditingContext() creates an EC in the _default_ OSC, not the
one you had created. Using an EO that is in an EC in a different
OSC will result in the error below. The relationships should be fine.
Which brings me to the subject of back, or inverse relationships.
I originally had created them for pretty much all my relationships
since that's the default behavior of EOModeler I think, but since
removing them a lot of my operations seem to be happening quicker.
Yes, you need to take care to use these only when needed and when
they contain a reasonably small number of objects.
Chuck
Jeff
On Aug 5, 2008, at 10:13 PM, Jeff Schmitz wrote:
OK, I took the thread completely out of the equation and call
updateResults directly from the main processing thread, but still
the first fetch I try using the new EC and Object Store
Coordinator I get the error:
java.lang.IllegalStateException: Attempt to access an EO that has
either not been inserted into any EOEditingContext or its
EOEditingContext has already been disposed
at
com
.webobjects.eocontrol.EOCustomObject.willRead(EOCustomObject.java:
1158)
at com.webobjects.eocontrol._EOMutableKnownKeyDictionary
$Initializer
$
_GenericRecordBinding
.valueInObject(_EOMutableKnownKeyDictionary.java:570)
at com.webobjects.eocontrol._EOMutableKnownKeyDictionary
$Initializer
$
_LazyGenericRecordBinding
.valueInObject(_EOMutableKnownKeyDictionary.java:613)
at
com
.webobjects
.eocontrol.EOCustomObject.storedValueForKey(EOCustomObject.java:
1634)
at com.netbracketsfw.model._Pricing.pools(_Pricing.java:86)
The _Pricing.pools call that is called as part of the fetch to
build the requested pools in the EC seems to be at least part of
the problem, but I have no idea why.
Jeff
On Aug 5, 2008, at 9:09 AM, Kieran Kelleher wrote:
Normally, the pattern I use is to create a separate class that
implements Runnable or Callable. Not sure if your use of an
inline anonymous class inside the WOComponent has anything to do
with your problem.... I just don't know since I don't use that
pattern for threads. Might be worth refactoring the threaded code
into a separate class...
On Aug 4, 2008, at 9:53 PM, Jeff Schmitz wrote:
Sure, here's how the thread is kicked off. updateResultsThread
and updateResults are both functions in the Component class.
public void updateResultsThread(final int winCmd) {
t = new Thread("updateResults") {
public void run() {
updateResults(winCmd);
}
};
t.start();
}
and here is everything in the updateResults function that occurs
up to the exception occuring:
public void updateResults(int winCmd) {
/* Provide the thread with its own access layer stack. */
EOObjectStoreCoordinator parentObjectStore = new
EOObjectStoreCoordinator();
EOEditingContext threadEditingContext = new
EOEditingContext(parentObjectStore);
//EOObjectStoreCoordinator rootObjectStore =
(EOObjectStoreCoordinator
)Session().defaultEditingContext().rootObjectStore();
try {
threadEditingContext.lock();
NSArray <Pool> pools =
Pool.fetchStandardPoolsByName(threadEditingContext);
There is a ton of other stuff that occurs after this point, but
the execution never gets that far.
Thanks!
Jeff
On Aug 4, 2008, at 6:20 AM, Kieran Kelleher wrote:
This may be just a trivial coding sequence problem Jeff.
Why not post your whole Runnable (or Callable) class so we can
see what you are doing ?
On Aug 4, 2008, at 12:01 AM, Jeff Schmitz wrote:
Hello,
Continuing on with trying to access EOs in a background
thread, I'm trying to give the background thread its own
EOObjectStoreCoordinator. To create a new
EOObjectStoreCoordinator, I'm using the following code:
EOObjectStoreCoordinator parentObjectStore = new
EOObjectStoreCoordinator();
EOEditingContext threadEditingContext = new
EOEditingContext(parentObjectStore);
However, when I try to fetch something into the
threadEditingContext using one of the static "fetch"
functions, I get an error:
INFO er.transaction.adaptor.Exceptions - Database Exception
occured: java.lang.IllegalStateException: Attempt to access an
EO that has either not been inserted into any EOEditingContext
or its EOEditingContext has already been disposed
Exception in thread "updateResults"
java.lang.IllegalStateException: Attempt to access an EO that
has either not been inserted into any EOEditingContext or its
EOEditingContext has already been disposed
at
com
.webobjects
.eocontrol.EOCustomObject.willRead(EOCustomObject.java:1158)
I kind of thought the static fetch operations were a way to
insert objects into EC's in the first place, so I'm a little
confused about the error. Is there something extra I need to
do because its not the default editing context?
below is more info on the fetch call I'm making if you'd want
to take a look. This is what I do after creating the
threadEditingContext...
try {
threadEditingContext.lock();
EOQualifier poolQual = Pool.POOL_TYPE.eq(Constants.FULLPOOL);
NSArray<EOSortOrdering> poolOrder = new
NSArray<EOSortOrdering>(
new EOSortOrdering(Pool.NAME_KEY,
EOSortOrdering.CompareAscending)); // Sort
return Pool.fetchPools(threadEditingContext, poolQual,
poolOrder);
// Below is the fetchPools function generated by the
EOGenerator:
public static NSArray<Pool> fetchPools(EOEditingContext
editingContext, EOQualifier qualifier, NSArray<EOSortOrdering>
sortOrderings) {
EOFetchSpecification fetchSpec = new
EOFetchSpecification(_Pool.ENTITY_NAME, qualifier,
sortOrderings);
fetchSpec.setIsDeep(true);
NSArray<Pool> eoObjects =
(NSArray
<Pool>)editingContext.objectsWithFetchSpecification(fetchSpec);
return eoObjects;
}
The error actually occurs on:
NSArray<Pool> eoObjects =
(NSArray
<Pool>)editingContext.objectsWithFetchSpecification(fetchSpec);
On Jul 30, 2008, at 8:25 AM, Kieran Kelleher wrote:
I have an app that does very long tasks like this a few times
a week. The tasks I have a *very* EOF intensive, as in
hammering the database usually for a very long time (4 to 24
hours)
Here is approach I use:
Create a Callable (or Runnable) class for the task.
Create setters/getters for any initial variables you need to
pass in. For EnterpriseObjects, just pass in the EOGlobalIDs,
not the objects themselves.
In the task method itself:
- Create a new ObjectStoreCoordinator (use Wonder OSC
synchronization if you want changes to propogate)
- Create any editing contexts using that single task OSC as
a parent
- lock and unlock your ec's manually when working with them
- depending on how much EO's you are fiddling with, memory
management can be challenging, so recycling ec's, and, dare I
say it, resorting to checking available memory and forcing
garbage collection when memory almost exhausted (some will
cringe at this, but extreme EOF just sucks memory and does
not let go fast enough ... depending on the conditions)
Tips
- Surround the task with a try/catch to get any errors
- Send an email to the user (if user initiated), or admin
(if necessary) notifying them of success, failure or error
when task is done (or error is thrown).
- Using log4j smtp appender for ERROR level is good too to
ensure errors in anonymous tasks are alerted to admin/devs
promptly.
On Jul 30, 2008, at 12:23 AM, Jeff Schmitz wrote:
Hello,
I have the need to kick off a VERY long (i.e. possibly up to
8-10 hour) background task that before it's through fetches
most of the contents of the database (via EO's of course)
and performs calculations on the data and saves the
calculated values back to the EOs many times during the
process. And oh, I'd like to have the results available to
the rest of my app as they are saved by the background task.
Currently btw, I do this with a java thread and don't really
use EOs, and I just return a page immediately after the
thread is kicked off, i.e. I don't really care about a
status page reloading for 8 hours as I'm the only user that
actually kicks off this process.
My first question is, now that I'm using EOs throughout my
app (including the background process) is there any reason
to use the WOLongResponsePage if I still don't care about
the status page? If so, there seems to be a dearth of
information on exactly how to use such a component. All I
can really find is a very terse API doc, and a few mentions
of its existance on the wiki. Any examples out there
anywhere?
I'll save my context locking and memory flushing questions
until after I've researched the subject a little more. From
what I can tell though, I'll want to create a new editing
context for the background thread (not sure about needing an
independent Object store coordinator for the background
process, but I don't think so), so that's a start.
Finally, anything in project Wonder that can help me? I did
run across this:
http://webobjects.mdimension.com/wonder/api/er/extensions/concurrency/class-use/ERXLongResponseTask.html#er.extensions.concurrency
but again, very terse docs.
Thanks,
Jeff
_______________________________________________
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
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (Webobjects-
email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
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
_______________________________________________
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
--
Chuck Hill Senior Consultant / VP Development
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