I realized about 5 minutes after I sent this that it *would* in fact cause circular reference problems. So, that wouldn't work.
This is a pretty tricky issue. The other solution I had would be to 'soft' commit the parent object to the cache until the entire map below it is materialized, and then hard commit it to the cache -- with only the methods that are materializing the references and collections having access to it (or you could put it to some temporary cache that is only available to that thread for materializing that map). -Andrew -----Original Message----- From: Clute, Andrew [mailto:[EMAIL PROTECTED] Sent: Thursday, January 29, 2004 3:00 PM To: OJB Users List Subject: RE: [PB API] concurrency problems Maybe I am missing something....but why not wait until the entire tree (collections and references) has been materialized before pushing the object on the cache? Or, is there a problem with circular references by doing that? -Andrew -----Original Message----- From: Armin Waibel [mailto:[EMAIL PROTECTED] Sent: Thursday, January 29, 2004 1:31 PM To: OJB Users List Subject: Re: [PB API] concurrency problems Hi Sven, I can reproduce your problem. It's a really nasty concurrency materialization problem when using global/shared caches and an object was materialized first time: Say we have a class Account with reference to Buyer, Buyer has a reference to Address and Address has a reference to AddressType (similar to your test case) Account -1:1- Buyer -1:1- Address -1:1- AddressType We set autoretrieve true. Thread_1: PB lookup Account object. Object was not found in cache, PB start to materialize Account and push this to cache, then first reference was materialized and pushed to cache,... Thread_2: PB lookup Account object. Object was found in cache and returned. But the found object is the same pushed by thread_1, thus PB returns a not full materialized Account object. If a local cache was used, e.g. ObjectCachePerBrokerImpl this situation will not arise. Solution is to set attribute 'refresh="true"' in all reference-descriptor. This force OJB to lookup each reference for an object whether or not it was found in cache. regards, Armin Sven Efftinge wrote: > I just changed ObjectCacheClass from DefaultImpl to EmptyImpl. > Without caching the test doesn't fail. > I think this happens because the threads don't have to share the > objects in this case. > Sven > > Sven Efftinge wrote: > >> Hi Armin, >> I wrote a test for this, now. >> Unfortunately I wrote it against my application, because I haven't >> installed the OJB test suite yet ;( The test starts n threads. Each >> thread creates a PersistentBroker, retrieves 4 instances of an entity >> and then checks some references for each entity. >> When I run the test for 1 thread the test passes. >> When I run it for e.g. 30 threads the test fails(most of the time) >> because some references were null. >> Mmh... the test fails to RC4, also. >> I'm not sure if this is really the same problem because I don't get >> any errors from OJB directly. Only the null references. >> >> Here is the test (I used GroboUtils from SF): >> >> public void testConcurrentRead() throws Throwable { >> int numthreads = 30; >> TestRunnable[] tests = new TestRunnable[numthreads]; >> >> for (int i = 0; i < tests.length; i++) { >> tests[i] = new FetchPersistentObjects(); >> } >> MultiThreadedTestRunner testRunner = >> new MultiThreadedTestRunner(tests); >> >> testRunner.runTestRunnables(); >> >> } >> >> class FetchPersistentObjects extends TestRunnable { >> /* (non-Javadoc) >> * @see net.sourceforge.groboutils.junit.v1.TestRunnable#runTest() >> */ >> public void runTest() throws Throwable { >> PersistenceBroker broker = null; >> KontoIF konto = null; >> try { >> broker = >> PersistenceBrokerFactory.createPersistenceBroker(pbKey); >> Criteria crit = new Criteria(); >> crit.addEqualTo(KONTO.NAME, "test"); >> QueryByCriteria query = new >> QueryByCriteria(Konto.class, crit); >> // we have 4 kontos with name="test" in the database >> List kontos = (List) broker.getCollectionByQuery(query); >> for (Iterator iter = kontos.iterator(); iter.hasNext();) { >> konto = (KontoIF) iter.next(); >> assertEquals("test", konto.getName()); >> assertNotNull("All kontos have a reference to an >> interessent", konto.getInteressent()); >> assertNotNull("All interessents have a reference >> to an adresse", konto.getInteressent().getAdresse()); >> assertNotNull("All adresses have a reference to an >> adresseart", konto.getInteressent().getAdresse().getAdresseart()); >> assertNotNull("All adressearts have a varname", >> konto.getInteressent().getAdresse().getAdresseart().getVarname()); >> } >> } finally { >> broker.close(); >> } >> } >> >> } >> >> Armin Waibel wrote: >> >>> Hi Sven, >>> >>> I don't know if your problem rely on a concurrency problem. Between >>> rc4 and rc5 I changed handling of DB resources in RsIterator class. >>> Now OJB is very strict in closing used resources. All resources will >>> be released when >>> - PB instance was closed >>> - PB commit call is done >>> - PB abort call is done >>> This helps to avoid abandoned Statement/ResultSet instances. >>> >>> > org.apache.ojb.broker.PersistenceBrokerException: >>> > org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException: >>> > Resources no longer reachable, RsIterator will be automatic >>> > cleaned up on PB.close/.commitTransaction/.abortTransaction >>> >>> The exception says that OJB has already closed the DB resources used >>> by the Iterator, e.g. one of the three events described above occur. >>> >>> Can you post the source code or some pseudo code where the exception >>> arise? >>> >>> regards, >>> Armin >>> >>> >>> Sven Efftinge wrote: >>> >>>> Hi, >>>> I just got some errors when using/retrieving the same >>>> persistentobjects in multiple threads (request cause it's a webapp). >>>> I tried many different configurations for class-descriptor, >>>> reference-descriptor, ... but the problem was still there. >>>> At the moment I only have proxy="dynamic" specified all other >>>> attributes are set to default. >>>> I only have the problem with OJB RC5. RC4 works fine. >>>> >>>> This is a sequence from the stacktraces: >>>> >>>> Caused by: org.apache.ojb.broker.PersistenceBrokerException: >>>> org.apache.ojb.broker.PersistenceBrokerException: >>>> org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException: >>>> Resources no longer reachable, RsIterator will be automatic cleaned >>>> up on PB.close/.commitTransaction/.abortTransaction >>>> at >>>> org.apache.ojb.broker.accesslayer.IndirectionHandler.materializeSub >>>> ject(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.accesslayer.IndirectionHandler.getRealSubject >>>> (Unknown >>>> Source) >>>> ... 33 more >>>> Caused by: org.apache.ojb.broker.PersistenceBrokerException: >>>> org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException: >>>> Resources no longer reachable, RsIterator will be automatic cleaned >>>> up on PB.close/.commitTransaction/.abortTransaction >>>> at >>>> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuer >>>> y(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuer >>>> y(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQue >>>> ry(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.accesslayer.BasePrefetcher.prefetchRelationsh >>>> ip(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.core.QueryReferenceBroker$PBPrefetchingListen >>>> er.prefetch(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.core.QueryReferenceBroker$PBMaterializationLi >>>> stener.beforeMaterialization(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.accesslayer.IndirectionHandler.beforeMaterial >>>> ization(Unknown >>>> Source) >>>> ... 35 more >>>> Caused by: >>>> org.apache.ojb.broker.accesslayer.RsIterator$ResourceClosedException: >>>> Resources no longer reachable, RsIterator will be automatic cleaned >>>> up on PB.close/.commitTransaction/.abortTransaction >>>> at >>>> org.apache.ojb.broker.accesslayer.RsIterator.getRsAndStmt(Unknown >>>> Source) >>>> at org.apache.ojb.broker.accesslayer.RsIterator.hasNext(Unknown >>>> Source) >>>> at >>>> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuer >>>> y(Unknown >>>> Source) >>>> ... 42 more >>>> >>>> Does this has to do with the "prefetch and autoRetreive"-problem >>>> discussed on this list in november? >>>> >>>> regards, >>>> Sven >>>> >>>> ------------------------------------------------------------------- >>>> -- To unsubscribe, e-mail: [EMAIL PROTECTED] >>>> For additional commands, e-mail: [EMAIL PROTECTED] >>>> >>>> >>>> >>> >>> >>> >>> -------------------------------------------------------------------- >>> - To unsubscribe, e-mail: [EMAIL PROTECTED] >>> For additional commands, e-mail: [EMAIL PROTECTED] >> >> >> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [EMAIL PROTECTED] >> For additional commands, e-mail: [EMAIL PROTECTED] > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
