Ok, as predicted I found a problem with using snapshot version counting in prefetching. Albeit a different kind of problem from what I expected - versions reset in the middle of prefetch processing to versions of the older cached snapshots. So reverted this to a heavier, but presumably fully reliable algorithm that simply collects all objects in a transaction-scoped HashMap.
Andrus On Jul 11, 2013, at 6:33 PM, Andrus Adamchik <[email protected]> wrote: > FYI .. this fix significantly changed the algorithm for refreshing prefetched > objects. When processing a prefetch tree of objects, and looking at a given > object, the new algorithm checks object's "snapshotVersion", and if it is >= > than the version of the first DataRow in the current transaction, it skips > the object refresh (assuming it was already refreshed in this tx). > > Aside from fixing "circular" prefetches, this also improves processing > performance in some cases where we've already tracked processed objects (only > via a separate HashMap). > > But now I am worrying that I overlooked something in my assumptions. > > I can think of a few hypothetical future scenarios when this might break if > we change this or that piece. E.g. "version of the first DataRow in the > current transaction" may not really be the first if we ever change processing > flow of a query. Or if we lift synchronization of updates from other contexts > and start getting updates from parallel transactions. > > Can't think of any scenario that might break the current stack. This doesn't > mean it does not exist :) So this is a call to early adopters who are running > trunk builds - please give us feedback on this feature! When you use > prefetching and see some objects not being refreshed, let's analyze your > query and see if this change is to blame. > > Thanks, > Andrus > > > > Begin forwarded message: >> From: "Andrus Adamchik (JIRA)" <[email protected]> >> Subject: [jira] [Closed] (CAY-1695) Unexpected null value in bidirectional >> one-to-one prefetch >> Date: July 10, 2013 6:41:49 PM GMT+03:00 >> To: [email protected] >> Reply-To: [email protected] >> >> >> [ >> https://issues.apache.org/jira/browse/CAY-1695?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel >> ] >> >> Andrus Adamchik closed CAY-1695. >> -------------------------------- >> >> Resolution: Fixed >> Fix Version/s: (was: 3.2M1) >> 3.2M2 >> >> Fixed for the attached unit test. The strategy used here is to grab the >> lowest version of the data row in a given transaction and use it as a marker >> to check against object versions. When creating an object, if we detect that >> it was already processed in this tx, we skip its processing. >> >>> Unexpected null value in bidirectional one-to-one prefetch >>> ---------------------------------------------------------- >>> >>> Key: CAY-1695 >>> URL: https://issues.apache.org/jira/browse/CAY-1695 >>> Project: Cayenne >>> Issue Type: Bug >>> Components: Core Library >>> Affects Versions: 3.1M3 >>> Reporter: Andrei Veprev >>> Fix For: 3.2M2 >>> >>> Attachments: >>> 0001-CAY-1695-Unexpected-null-value-in-bidirectional-one-.patch, >>> CAY-1695-test.patch >>> >>> >>> For example you have User and UserInfo entities. User has one-to-one >>> relationship with UserInfo. If you try to do select for User with >>> prefetching on userInfo and userInfo.user, you will get null value for >>> userInfo property: >>> SelectQuery query = new SelectQuery(User.class); >>> query.addPrefetch("userInfo"); >>> query.addPrefetch("userInfo.user"); >>> It doest meter which kind of prefetching do you use. >> >> -- >> This message is automatically generated by JIRA. >> If you think it was sent incorrectly, please contact your JIRA administrators >> For more information on JIRA, see: http://www.atlassian.com/software/jira >> > >
