You should do something like
ERXLongResponse csvTask(ERXGenericRecord eo) {
EOGlobalID gid = eo.permanentGlobalID();
ImportCSVTask task = new ImportCSVTask(gid);
...
}
class ImportCSVTask {
private EOGlobalID _gid;
ImportCSVTask(EOGlobalID gid) {
_gid = gid;
}
performAction() {
//Safe here. Method called by the background thread
EOEditingContext ec = ERXEC.newEditingContext();
EOEnterpriseObject eo =
ERXEOGlobalIDUtilities.fetchObjectWithGlobalID(ec, _gid);
//Do stuff
}
}
You grab the gid, pass it to the runner, then when the background thread calls
run() on the runner, return the gid to an eo. Use wonder classes to do this
like the ERXLongResponseTask mentioned or an ERXRunnable since those do the
auto locking magic for you.
On Jan 29, 2015, at 10:33 AM, OC <[email protected]> wrote:
> Ramsey,
>
>> Can’t really tell looking a pseudo code, but I’ll take a guess.
>
> that's my very real code, just I've removed things unrelated (hundreds of
> lines) to keep it manageable -- if possible, removing them altogether, if
> not, at least replacing them by "... description ...". But what remained is
> copy/pasted from Xcode.
>
>> Auto locking works on a single thread. You can’t pass EOs to a background
>> thread. You need to pass EOGlobalIDs to your runnable constructor instead
>> and then create your new ec on the background thread when you begin
>> processing. Your constructor is passing full EOs and thus you are getting
>> weird behavior.
>
> Ha! That's a news for me. I thought passing EOs is all right, supposed I make
> sure the passed EO always gets translated to the background thread's EC using
> localInstanceIn.
>
> Just to make sure I understand you properly: to fix my code, I should replace
>
>>> ownerEO=ownerEO.localInstanceIn(ec)
>
> by
>
> ownerEO=ec.faultForGlobalID(ownerEO.editingContext().globalIDForObject(ownerEO))
>
> and similarly, I should replace
>
>>> old.localInstanceIn(ownerEO.editingContext()).owner=null //
>>> owned relationship -> will delete
>
> by
>
> ownerEO.editingContext().faultForGlobalID(old.editingContext().globalIDForObject(old)).owner=null
>
> so that it works reliably, right?
>
> Thanks a big lot!
> OC
>
>> On Jan 29, 2015, at 9:41 AM, OC <[email protected]> wrote:
>>
>>> Hello there,
>>>
>>> well, the last fixes seem to have helped, at least, so far no problem
>>> related.
>>>
>>> Today though I've found one new problem, (hopefully) unrelated -- an EO
>>> somehow lost its EC?!?
>>>
>>> The user can import CSV; since it takes a small eternity, the import runs
>>> in a background task. The code essential skeleton looks like this:
>>>
>>> ===
>>> static ERXLongResponseTask csvTask(EOEnterpriseObject ownerEO) {
>>> NSArray originalObjects=ownerEO.ownedObjects().clone() // note they
>>> are in old EC (legacy code reasons)
>>> ERXEC ec=ERXEC.newEditingContext()
>>> ec.lock() // do I really need to lock here?
>>> try {
>>> ownerEO=ownerEO.localInstanceIn(ec)
>>> } finally {
>>> ec.unlock()
>>> }
>>> def task=new ImportCSVTask(ownerEO:ownerEO, original:originalObjects)
>>> task.start()
>>> task
>>> }
>>> ...
>>> class ImportCSVTask extends ERXLongResponseTask.DefaultImplementation {
>>> EOEnterpriseObject ownerEO
>>> NSArray original
>>> def performAction {
>>> try {
>>> for (... CSV reader and parser, line loop ...) {
>>> EOEnterpriseObject
>>> record=EOUtilities.createAndInsertInstance(ownerEO.editingContext(),"DBRecord")
>>> println "-> $record"
>>> record.owner=ownerEO
>>> ... set up record contents from CSV fields ...
>>> }
>>> for (old in original)
>>> old.localInstanceIn(ownerEO.editingContext()).owner=null //
>>> owned relationship -> will delete
>>> ownerEO.editingContext().saveChanges() // line 237
>>> } catch (exc) {
>>> ... error management ...
>>> }
>>> }
>>> }
>>> ===
>>>
>>> For about zillion times, the code worked all right; nevertheless, today,
>>> saving crashed, and I've found this in my log (the <class@hasCode
>>> primaryKey EC> is my own overridden toString, which simply prints
>>> "/EC:this.editingContext()" or "/NULL-EC" in case
>>> this.editingContext()==null; note also 0x27fcc396==670876566):
>>>
>>> ===
>>> ...
>>> -> <DBRecord@278683965 PK:null N /EC:670876566>
>>> ... 1500-odd more of similar ones ...
>>> -> <DBRecord@653822193 PK:null N /EC:670876566>
>>> ... 1500-odd more of similar ones ...
>>> -> <DBRecord@1291010302 PK:null N /EC:670876566>
>>> java.lang.IllegalStateException: Cannot obtain globalId for an object which
>>> is not registered in any editingContext, object: <DBRecord@653822193
>>> PK:null N /NULL-EC>, databaseContext:
>>> com.webobjects.eoaccess.EODatabaseContext@8fea539, object's editingContext:
>>> null, databaseContext's active editingContext:
>>> er.extensions.eof.ERXEC@27fcc396
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext._globalIDForObject(EODatabaseContext.java:4660)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.databaseOperationForObject(EODatabaseContext.java:4767)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.recordUpdateForObject(EODatabaseContext.java:6076)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.relayAttributesInRelationshipSourceObjectDestinationObject(EODatabaseContext.java:4921)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.relayAttributesInRelationshipSourceObjectDestinationObjects(EODatabaseContext.java:4966)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.recordChangesInEditingContext(EODatabaseContext.java:6036)
>>> at
>>> com.webobjects.eocontrol.EOObjectStoreCoordinator.saveChangesInEditingContext(EOObjectStoreCoordinator.java:373)
>>> at
>>> com.webobjects.eocontrol.EOEditingContext.saveChanges(EOEditingContext.java:3192)
>>> at er.extensions.eof.ERXEC._saveChanges(ERXEC.java:1179)
>>> at er.extensions.eof.ERXEC.saveChanges(ERXEC.java:1102)
>>> at er.extensions.eof.ERXEC$saveChanges$1.call(Unknown Source)
>>> at others.ImportCSVTask.performAction(CSVImport.groovy:237)
>>> ===
>>>
>>> Other threads did save other EC's meantime, but far as I can say, neither
>>> this temporary EC nor the objects created here were touched anyhow from
>>> other threads.
>>>
>>> As always, I'll be grateful for any idea what might lead to this
>>> abomination :-O
>>>
>>> Thanks,
>>> OC
>>>
>>>
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list ([email protected])
>>> Help/Unsubscribe/Update your Subscription:
>>> https://lists.apple.com/mailman/options/webobjects-dev/rgurley%40smarthealth.com
>>>
>>> This email sent to [email protected]
>>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]