Shared Cache and relationships

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Shared Cache and relationships

Lon Varscsak
So previously this year, I posted about about how while fetching an object
that it’s relationships weren’t automatically refreshing, even though I was
not caching (myself) any data.  This is where I learned about “shared
caches” and realized that if I turned it off, I kind of get the behavior I
want (except now peer synchronization doesn’t work).  Data within a single
context is cached (if I choose), but once the context is gone, the
snapshots are gone.  It doesn’t seem to make sense that a global cache
would hold onto snapshots beyond the life of the objects across
contexts…but that’s what it appears to do.

The response was, “refresh your relationships with prefetches”.  This
doesn’t seem like a clean solution to me.  It forces the developer to “be
aware” of stale data and force fetches on relationships that they might not
need in that moment.  Realize that a lot of components in my application
might shared data (like a Customer, or an Order), but the components don’t
necessarily access all of the information in those relationships.  I
believe EOF, the snapshot would decrement to 0 (when that snapshot wasn’t
referred to anymore by any context) and the next fetch would be fresh.  Is
there no concept like this for Cayenne?

Any help would be appreciated.  It’s very possible I’m just missing the
obvious approach.

-Lon
Reply | Threaded
Open this post in threaded view
|

Re: Shared Cache and relationships

dollj
Hi Lon

Here is my kludge/hack of how I handle the problem of when "fetching an
object that it’s relationships weren’t automatically refreshing".
It's based on Cayenne storing a fault object in the data map to indicate
that the relationship hasn't been fetched yet.
Note, that I don't think this works if the relationship is being prefetched.

public class Patient extends _Patient
{
    private Object  historyFault;
    private long  lastHistoryAccess;
    private final long  ONE_SECOND = 1000;

    @Override
    public PatientHistory getMedicalHistory()
    {
        if ( historyFault == null )  historyFault = readPropertyDirectly(
MEDICAL_HISTORY_PROPERTY );
        else  if ( System.currentTimeMillis() - lastHistoryAccess >
ONE_SECOND )
        {
            getObjectContext().invalidateObjects(
super.getMedicalHistory() );       // Forces refresh of objects.
            writePropertyDirectly( MEDICAL_HISTORY_PROPERTY, historyFault );
// Forces refetch.
        }
        lastHistoryAccess = System.currentTimeMillis();
        return = super.getMedicalHistory();
    }
}

If you only want to refetch in specific instances then put the "else" clause
into a separate method and call that when appropriate.

Hope this helps, regards
Jurgen


-----Original Message-----
From: Lon Varscsak
Sent: Thursday, November 17, 2016 12:41 AM
To: Apache Cayenne
Subject: Shared Cache and relationships

So previously this year, I posted about about how while fetching an object
that it’s relationships weren’t automatically refreshing, even though I was
not caching (myself) any data.  This is where I learned about “shared
caches” and realized that if I turned it off, I kind of get the behavior I
want (except now peer synchronization doesn’t work).  Data within a single
context is cached (if I choose), but once the context is gone, the
snapshots are gone.  It doesn’t seem to make sense that a global cache
would hold onto snapshots beyond the life of the objects across
contexts…but that’s what it appears to do.

The response was, “refresh your relationships with prefetches”.  This
doesn’t seem like a clean solution to me.  It forces the developer to “be
aware” of stale data and force fetches on relationships that they might not
need in that moment.  Realize that a lot of components in my application
might shared data (like a Customer, or an Order), but the components don’t
necessarily access all of the information in those relationships.  I
believe EOF, the snapshot would decrement to 0 (when that snapshot wasn’t
referred to anymore by any context) and the next fetch would be fresh.  Is
there no concept like this for Cayenne?

Any help would be appreciated.  It’s very possible I’m just missing the
obvious approach.

-Lon