Hello everyone, I'm sporadically getting the following error thrown as a result of a routine I've written. InvalidObjectReference: Attempt to store a reference to an object from a separate connection to the same database or multidatabase. I can often run this routine several times without a problem. After a fresh Zope (re)start, this error never happens on the first run. Once the problem does occur I need to restart Zope to make it go away. Can anyone tell me what this error actually means, and what bad practices could cause it? I've found a couple of hits about "InvalidObjectReference: Attempt to store an object from a foreign database connection error" in the archives, but I don't know how close this is to my problem. An example traceback would be: ----------------------------------------------- 2006-11-08T16:47:49 ERROR Zope.SiteErrorLog http://localhost:8080/WebSites/dev/test1/manage_publish Traceback (innermost last): Module ZPublisher.Publish, line 115, in publish Module ZPublisher.mapply, line 88, in mapply Module ZPublisher.Publish, line 41, in call_object Module Products.DWT.WebBase, line 756, in manage_publish Module Products.DWT.WebBase, line 724, in manage_publish Module OFS.CopySupport, line 564, in _getCopy Module transaction._manager, line 110, in savepoint Module transaction._transaction, line 295, in savepoint Module transaction._transaction, line 292, in savepoint Module transaction._transaction, line 675, in __init__ Module ZODB.Connection, line 1012, in savepoint Module ZODB.Connection, line 526, in _commit Module ZODB.Connection, line 553, in _store_objects Module ZODB.serialize, line 407, in serialize Module ZODB.serialize, line 416, in _dump Module ZODB.serialize, line 341, in persistent_id InvalidObjectReference: Attempt to store a reference to an object from a separate connection to the same database or multidatabase ----------------------------------------------- I'm only dealing with one ZODB, so perhaps this is a multiple connection issue (although I have no idea how/why). In case it helps to know the context of the problem, I have a collection of objects I've written: 1) WebSite, based on OrderedFolder 2) WebSection, based on OrderedFolder 3) WebPage, based on ZopePageTemplate 4) WebImage, based on Image. Each of these classes inherit a common base of functionality from a WebBase class. The manage_publish() method, defined in WebBase, copies the current object (one of #'s 2-4) to the same relative path within the context of another WebSite. This gives me a basic "dev" to "live" publishing process. Perhaps the most complex part of this routine is its ability to recurse. For example, a WebPage on the dev WebSite will first call its parent WebSection's manage_publish() if the parent WebSection doesn't exist on the live WebSite. Other things do happen during the process which might be causing this InvalidObjectReference, but if I can get a grip on what kinds of programming offenses causes this exception then I can make a more educated review of my code. I will happily provide a copy of the source if anyone is interested or thinks it will be useful. Thank you for any help or advice! Garth
Garth B. wrote at 2006-11-9 11:21 -0500:
I'm sporadically getting the following error thrown as a result of a routine I've written.
InvalidObjectReference: Attempt to store a reference to an object from a separate connection to the same database or multidatabase.
This is in indication that you have introduced a persistency bug: It is very essential that you use a persistent object only in the context of the ZODB connection that loaded this object. Failing to fulfill this requirement can lead to several kinds of difficult to understand errors. The one, you see above is one such kind. Apparently, you try to store a persistent object from a connection "C1" as attribute of a persistent object from a different connection "C2". The bug is usually introduced by storing persistent objects outside of their connection cache -- e.g. on class level or in a module level cache. -- Dieter
Ok, I understand in theory what the problem is, I'm just not clear where in code this could be happening. I'm not consciously manipulating connections and I guess Zope is taking care of those low-level connection details with the ZODB for me. Can I programmatically determine whether an object is already loaded/cached by a different connection? Would it help to try isolate this routine to a single connection? *Can* I isolate this routine to a single connection? You know, I'm starting to think that my fancy little recursion between objects is what's royally screwing things up. A lot of loading of objects occurs here, possibly touching on the same objects between calls... Any other pointers/hints are welcome! Thank you Dieter and anyone else who can help out! Garth On 11/9/06, Dieter Maurer <dieter@handshake.de> wrote:
Garth B. wrote at 2006-11-9 11:21 -0500:
I'm sporadically getting the following error thrown as a result of a routine I've written.
InvalidObjectReference: Attempt to store a reference to an object from a separate connection to the same database or multidatabase.
This is in indication that you have introduced a persistency bug:
It is very essential that you use a persistent object only in the context of the ZODB connection that loaded this object.
Failing to fulfill this requirement can lead to several kinds of difficult to understand errors. The one, you see above is one such kind.
Apparently, you try to store a persistent object from a connection "C1" as attribute of a persistent object from a different connection "C2".
The bug is usually introduced by storing persistent objects outside of their connection cache -- e.g. on class level or in a module level cache.
-- Dieter
Garth B. wrote at 2006-11-9 16:29 -0500:
... Can I programmatically determine whether an object is already loaded/cached by a different connection?
The connection an object "o" belongs to is accessed via "o._p_jar".
Would it help to try isolate this routine to a single connection? *Can* I isolate this routine to a single connection?
Usually, a Zope application will in each request only deal with objects from the same connection. Some class or module level storage for objects is usually involved when problems such as observed by you arise. Of course, I cannot tell you, where in your application is something like this... -- Dieter
Garth B. wrote:
I'm sporadically getting the following error thrown as a result of a routine I've written.
The routine is likely not managing its connections properly. What does this routine look like? Can you boil it down to a simple example which fails? cheers, Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk
participants (3)
-
Chris Withers -
Dieter Maurer -
Garth B.