| Avoiding N+One Selects and stale BatchValueHolders [message #666808] |
Fri, 22 April 2011 13:33  |
Michael Mising name Messages: 9 Registered: April 2011 |
Junior Member |
|
|
I'm trying to cut down the number of n+1 selects incurred by my application, in as many places as possible I've tried to add the batch read hint to queries. In a large number of places in the app I don't always know exactly what relationships I'll be traversing (My view displays fields based on user preferences). At that point I'd like to run one query to populate all of those relationships for my objects.
My dream is to call something like ReadAllRelationshipsQuery(Collection,RelationshipName) and populate all of these items so that later calls to:
Collection.get(0).getMyStuff will already be populated and not cause a db query. How can I accomplish this? I'm willing to write any code I need to but I can't find a way that works with eclipselink?
-- Why don't I just batch read all of the possible fields and let them load lazily? What I've found is that the batch value holders that implement batch reads don't behave well with the eclipselink cache. If a batch read value holder isn't "evaluated" and ends up in the eclipse link cache it can become stale and return incorrect data (This behavior was logged as a bug by someone else but rejected...)
How do I avoid N+1 selects for objects/collections I already have a reference to?
|
|
|
|
|
|
|
|
| Re: Avoiding N+One Selects and stale BatchValueHolders [message #667431 is a reply to message #667406] |
Thu, 28 April 2011 13:17   |
Michael Mising name Messages: 9 Registered: April 2011 |
Junior Member |
|
|
The data that is used for the where clause of the BatchValueHolder won't necessarily be related to the relationship that returns incorrect results. For instance if I batch read notes on a query like this:
SELECT * FROM USERS WHERE NUMBEROFFRIENDS = 5;
If I do not immediately call getNotes on those users I have a potential problem. Here is the scenario:
A 2nd request comes in an says add one friend to User 12
A 3rd request comes in and says show me all of User 12's notes (A direct call for User 12 pulls the object out of the identity map)
User12.getNotes() then issues the query:
SELECT NOTES.* FROM NOTES, USERS WHERE NUMBEROFFRIENDS = 5;
This returns 0 notes for User12 because this user now has 6 friends.
I see just about any BatchValueHolder in the global IdentityMap as dangerous?
To avoid this we've stopped using BatchRead hints when we can't guarantee they will be immediately evaluated but that defeats the point of indirection.
Is there a way to change a value holder from a batch value holder back to a standard value holder before abandoning the object? What is the best way to avoid this?
Thanks for your help!
Michael
EDIT: The closer I look at bug 326197 the more I think it isn't perfectly related.
[Updated on: Thu, 28 April 2011 13:21] Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.03102 seconds