From fe8e6ebf053014bd5ff3e35a6fc3399a89c73521 Mon Sep 17 00:00:00 2001 From: Leonardo Rochael Almeida <leonardo@nexedi.com> Date: Thu, 4 Mar 2010 21:29:38 +0000 Subject: [PATCH] flush all ZODB caches when importing new synthetic modules, so cached objects don't behave as their old classes git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@33408 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/Document/BusinessTemplate.py | 10 ++++++++++ product/ERP5/tests/testBusinessTemplate.py | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py index b07b8429f2..a857090042 100644 --- a/product/ERP5/Document/BusinessTemplate.py +++ b/product/ERP5/Document/BusinessTemplate.py @@ -3147,6 +3147,16 @@ class DocumentTemplateItem(BaseTemplateItem): continue if self.local_file_importer_name is not None: globals()[self.local_file_importer_name](name) + # after any import, flush all ZODB caches to force a DB reload + # otherwise we could have objects trying to get commited while + # holding reference to a class that is no longer the same one as + # the class in its import location and pickle doesn't tolerate it. + # First we do a savepoint to dump dirty objects to temporary + # storage, so that all references to them can be freed. + transaction.savepoint(optimistic=True) + # Then we need to flush from all caches, not only the one from this + # connection + self.getPortalObject()._p_jar.db().cacheMinimize() else: BaseTemplateItem.install(self, context, trashbin, **kw) for id in self._archive.keys(): diff --git a/product/ERP5/tests/testBusinessTemplate.py b/product/ERP5/tests/testBusinessTemplate.py index 4185fdf246..a1bca8ef8f 100644 --- a/product/ERP5/tests/testBusinessTemplate.py +++ b/product/ERP5/tests/testBusinessTemplate.py @@ -5988,6 +5988,14 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): template_tool = self.portal.portal_templates bt_path = os.path.join(os.path.dirname(__file__), 'test_data', self._testMethodName) + # create a previously existing instance of the overriden document type + from Products.ERP5Type.Document.File import File + from Products.CMFDefault.File import File as BaseFile + self.portal._setObject('another_file', File('another_file')) + transaction.commit() + self.tic() + # check its class has not yet been overriden + self.assertTrue(isinstance(self.portal.another_file, BaseFile)) for i in xrange(6): marker_list.append(i) gc.disable() @@ -6001,6 +6009,9 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): self.assertEqual(self.portal.some_file.int_index, i) transaction.commit() self.tic() + # check the previously existing instance now behaves as the overriden + # class + self.assertFalse(isinstance(self.portal.another_file, BaseFile)) finally: BaseTemplateItem.removeProperties = BaseTemplateItem_removeProperties SimpleItem._getCopy = SimpleItem_getCopy -- 2.30.9