Need some help to get rid of an InvalidObjectReference exception
Need some help to get rid of an InvalidObjectReference exception Hi zopers, In my zope product, when I try to put some specific object in the session, I get this : 2008-08-18T14:51:02 ERROR(200) SiteError http://www.afdas.com:8091/noyauafdas/tests/testAdresses Traceback (most recent call last): File "/opt/Zope-2.7/lib/python/ZPublisher/Publish.py", line 107, in publish transactions_manager.commit() File "/opt/Zope-2.7/lib/python/Zope/App/startup.py", line 222, in commit get_transaction().commit() File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 241, in commit ncommitted += self._commit_objects(objects) File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 356, in _commit_objects jar.commit(o, self) File "/opt/Zope-2.7/lib/python/ZODB/Connection.py", line 452, in commit dump(state) InvalidObjectReference: Attempt to store an object from a foreign database connection after hours of googling and debugging (not very easy because traceback does not show the line of your product code that fired the exception), I found the line that is breaking everything. def remonterAdresses(self,p_idEntreprise=0): """ Sans arguments, cette methode retourne les adresses stockees en session. """ # XXX : attention, p_idEntreprise est totalement ignore si entreprise deja en session entreprise = self.REQUEST.SESSION.get('entreprise') print "GestionnaireEntreprises::remonterAdresses..." if not entreprise : entreprise = Entreprise(self,p_idEntreprise) print "mise de entreprise en session.." self.REQUEST.SESSION.set('entreprise',entreprise) print "...mise en session OK" adresses = entreprise.remonterAdresses() print "GestionnaireEntreprises::remonterAdresses OK, adresses = ",adresses return adresses Now, the bug comes form the line self.REQUEST.SESSION.set('entreprise',entreprise) entreprise is an instance of Entreprise. I never put objects of this class in the ZODB because I don't need them to persist, they're just temporary. However, because Entreprises objects need to access to other objects that are in the ZODB, I pass them self as first argument, so that they can use it as a "context" to acquire other objects (for examples, Z SQL Methods). So inside Entreprise code, I can do something like self.context.zsql_method_something... because self.context is a reference to the caller, which lives in the ZODB. The caller is gestionnaireEntrprises. So my question is : what is wrong with that ? Why do I get this InvalidObjectReference ? is it the entreprise object that is in the session ? is it the gestionnaireEntreprises that is stored as an attribute of the entreprise object ? maybe both ? Thank you for any advice. Zope 2.7 python 2.3 plone 2.0.5
chaouche yacine wrote at 2008-8-18 09:50 -0700:
Need some help to get rid of an InvalidObjectReference exception In my zope product, when I try to put some specific object in the session, I get this :
2008-08-18T14:51:02 ERROR(200) SiteError http://www.afdas.com:8091/noyauafdas/tests/testAdresses Traceback (most recent call last): File "/opt/Zope-2.7/lib/python/ZPublisher/Publish.py", line 107, in publish transactions_manager.commit() File "/opt/Zope-2.7/lib/python/Zope/App/startup.py", line 222, in commit get_transaction().commit() File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 241, in commit ncommitted += self._commit_objects(objects) File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 356, in _commit_objects jar.commit(o, self) File "/opt/Zope-2.7/lib/python/ZODB/Connection.py", line 452, in commit dump(state) InvalidObjectReference: Attempt to store an object from a foreign database connection
A given persistent object can only be in one (ZODB-) database, not in several databases at the same time. You must copy the persistent object, when you want it to be stored (also) in another (ZODB-) database. You can use the "_getCopy(destination)" method to create such a copy. "_getCopy" is defined by "OFS.CopySupport.CopySource" inherited by most Zope objects. -- Dieter
Need some help to get rid of an InvalidObjectReference exception In my zope product, when I try to put some specific object in the session, I get this :
2008-08-18T14:51:02 ERROR(200) SiteError http://www.afdas.com:8091/noyauafdas/tests/testAdresses Traceback (most recent call last): File "/opt/Zope-2.7/lib/python/ZPublisher/Publish.py", line 107, in publish transactions_manager.commit() File "/opt/Zope-2.7/lib/python/Zope/App/startup.py", line 222, in commit get_transaction().commit() File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 241, in commit ncommitted += self._commit_objects(objects) File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 356, in _commit_objects jar.commit(o, self) File "/opt/Zope-2.7/lib/python/ZODB/Connection.py", line 452, in commit dump(state) InvalidObjectReference: Attempt to store an object from a foreign database connection
A given persistent object can only be in one (ZODB-) database, not in several databases at the same time.
You must copy the persistent object, when you want it to be stored (also) in another (ZODB-) database.
You can use the "_getCopy(destination)" method to create such a copy. "_getCopy" is defined by "OFS.CopySupport.CopySource" inherited by most Zope objects.
-- Dieter
Well if it is the case, I didn't do it on purpose because I didn't use any specific ZODB code to copy objects on different ZODBs. How do I know to which ZODB a specific object belongs to ?
chaouche yacine wrote at 2008-8-20 01:52 -0700:
... How do I know to which ZODB a specific object belongs to ?
A persistent object has the attribute "_p_jar". This attribute is "None" when the object was not loaded from the ZODB and otherwise, it is the ZODB connection which has loaded it. A ZODB connection has the method "db()" (or similar) which returns the ZODB database this connection belongs to. More details in the source ("ZODB.DB" and "ZODB.Connection"). -- Dieter
--- On Tue, 8/19/08, Dieter Maurer <dieter@handshake.de> wrote:
From: Dieter Maurer <dieter@handshake.de> Subject: Re: [Zope] Need some help to get rid of an InvalidObjectReference exception To: yacinechaouche@yahoo.com Cc: zope@zope.org Date: Tuesday, August 19, 2008, 11:16 AM chaouche yacine wrote at 2008-8-18 09:50 -0700:
Need some help to get rid of an InvalidObjectReference exception In my zope product, when I try to put some specific object in the session, I get this :
2008-08-18T14:51:02 ERROR(200) SiteError http://www.afdas.com:8091/noyauafdas/tests/testAdresses Traceback (most recent call last): File "/opt/Zope-2.7/lib/python/ZPublisher/Publish.py", line 107, in publish transactions_manager.commit() File "/opt/Zope-2.7/lib/python/Zope/App/startup.py", line 222, in commit get_transaction().commit() File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 241, in commit ncommitted += self._commit_objects(objects) File "/opt/Zope-2.7/lib/python/ZODB/Transaction.py", line 356, in _commit_objects jar.commit(o, self) File "/opt/Zope-2.7/lib/python/ZODB/Connection.py", line 452, in commit dump(state) InvalidObjectReference: Attempt to store an object from a foreign database connection
A given persistent object can only be in one (ZODB-) database, not in several databases at the same time.
You must copy the persistent object, when you want it to be stored (also) in another (ZODB-) database.
You can use the "_getCopy(destination)" method to create such a copy. "_getCopy" is defined by "OFS.CopySupport.CopySource" inherited by most Zope objects.
-- Dieter
I narrowed the code to what is necessary to fire this exception, and here is the tarball for those who want to test it live http://yacinechaouche.googlepages.com/InvalidObjectReferenceExample.tgz This is the directory contents : + InvalidObjectReferenceExample \_ __init__.py \_ NonZODBObject.py \_+ zmi \_ ZODBLivingObjectAddForm.pt \_ ZODBLivingObject.py ================ NonZODBObject.py ================ class NonZODBObject: """ Hello, i do not live in the ZODB """ def __init__(self,p_context): """ """ # This is the evil line. self.context = p_context =================== ZODBLivingObject.py =================== from OFS.SimpleItem import SimpleItem from NonZODBObject import NonZODBObject class ZODBLivingObject(SimpleItem) : """ Hello, I live in the ZODB. """ meta_type = "ZODBish" def __init__(self): """ """ self.id = "ZODBish" self.title = "ZODBish" def breakEverything(self): """ """ nonZODBish = NonZODBObject(self) # This line breaks everything. self.REQUEST.SESSION.set('breakish',nonZODBish) # This can be seen in the console if runzope print "it's me",nonZODBish.context return nonZODBish.context __init__.py contains the code necessary to create a ZODBish in the ZODB through the ZMI zmi contains the form that adds a ZODBish through the ZMI As you see, I do not intentionally copy objects from one ZODB to another... Except maybe if the session has a separate storage and that this breaks everything. But then, I could not even use the _getCopy method because nonZODBish do not have a _p_jar attribute. Any help or comment would be appreciated .
participants (2)
-
chaouche yacine -
Dieter Maurer