FAQ
Hi everybody.

I'm trying to add caching support (query cache) to a project which uses cayenne.
For what I understood in the online documentation there are two types of caches: local and shared.
Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache.

Now... the problem.. I have a query cached (a sort of select * from table) and a new row is added in the table. I would like that the next time the same query is called also the new row is fetched.

This is the query cache

SelectQuery select = new SelectQuery(t);
Class t; //this is the class of the persistent object to be fetched
select.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);

select.setCacheGroups(t.getName());

This is my "sample" test code (Network is a Cayenne Object class) (GetAllNetwork is a selectquery with the above caching. AddNetwork adds a new object and commit it. A new DataContext is used every time)

List<Network> networks = dbHandle.GetAllNetwork();
Network net = dbHandle.AddNetwork();
List<Network> newNetworks = dbHandle.GetAllNetwork();

assertEquals(networks.size() + 1, newNetworks.size());


Now... my assert is not true, because the query is cached.
I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

private void clearCache(Object entity) {
Persistent object = (Persistent)entity;
QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
cache.removeGroup(object.getClass().getName());
}

Any help?

Thanks
Regards

Francesco Romano

Search Discussions

  • Andrus Adamchik at Aug 22, 2012 at 1:04 pm

    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache. Correct.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    This is going in the right direction. So is listener method invoked, but the cache is not cleared, or the listener method is never invoked.

    BTW Cayenne 3.1 has a nice set of extensions called cayenne-lifecycle. The docs are still sparse (we are working on those), but there is a @CacheGroups annotation placed on persistent classes that tells Cayenne that any changes to a given type of objects should generate a cache invalidation event. E.g.:

    @CacheGroups("news")
    public class News extends com.foo.auto._News { }

    processing of this annotation is enabled by installing org.apache.cayenne.lifecycle.cache.CacheInvalidationFilter (also part of cayenne-lifecycle):

    DataChannelFilter filter = new CacheInvalidationFilter();

    CayenneRuntime runtime = ...

    // a bit clunky.. may merge the following 2 lines in one in the future releases:
    runtime.getDataDomain().addFilter(filter);
    runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(filter);

    Cheers,
    Andrus

    On Aug 21, 2012, at 6:36 PM, Francesco Romano wrote:
    Hi everybody.

    I'm trying to add caching support (query cache) to a project which uses cayenne.
    For what I understood in the online documentation there are two types of caches: local and shared.
    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache.

    Now... the problem.. I have a query cached (a sort of select * from table) and a new row is added in the table. I would like that the next time the same query is called also the new row is fetched.

    This is the query cache

    SelectQuery select = new SelectQuery(t);
    Class t; //this is the class of the persistent object to be fetched
    select.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);

    select.setCacheGroups(t.getName());

    This is my "sample" test code (Network is a Cayenne Object class) (GetAllNetwork is a selectquery with the above caching. AddNetwork adds a new object and commit it. A new DataContext is used every time)

    List<Network> networks = dbHandle.GetAllNetwork();
    Network net = dbHandle.AddNetwork();
    List<Network> newNetworks = dbHandle.GetAllNetwork();

    assertEquals(networks.size() + 1, newNetworks.size());


    Now... my assert is not true, because the query is cached.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }

    Any help?

    Thanks
    Regards

    Francesco Romano
  • Andrus Adamchik at Aug 22, 2012 at 1:10 pm

    On Aug 22, 2012, at 4:04 PM, Andrus Adamchik wrote:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    This is going in the right direction. So is listener method invoked, but the cache is not cleared, or the listener method is never invoked.
    BTW, could it be that the cache you are invalidating is a local cache? IIRC before Cayenne 3.1 this would not propagate to the shared cache (it will in 3.1). So you'd need to access QueryCache of DataDomain, which is the shared cache.

    Andrus
  • Francesco Romano at Aug 22, 2012 at 1:13 pm

    On Aug 22, 2012, at 3:04 PM, Andrus Adamchik wrote:

    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache. Correct.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    This is going in the right direction. So is listener method invoked, but the cache is not cleared, or the listener method is never invoked.

    BTW Cayenne 3.1 has a nice set of extensions called cayenne-lifecycle. The docs are still sparse (we are working on those), but there is a @CacheGroups annotation placed on persistent classes that tells Cayenne that any changes to a given type of objects should generate a cache invalidation event. E.g.:

    @CacheGroups("news")
    public class News extends com.foo.auto._News { }

    processing of this annotation is enabled by installing org.apache.cayenne.lifecycle.cache.CacheInvalidationFilter (also part of cayenne-lifecycle):

    DataChannelFilter filter = new CacheInvalidationFilter();

    CayenneRuntime runtime = ...

    // a bit clunky.. may merge the following 2 lines in one in the future releases:
    runtime.getDataDomain().addFilter(filter);
    runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(filter);

    Cheers,
    Andrus
    Thank you for your answer.
    I don't think we can update our cayenne right now, but we will take a look at the annotations asap (it means: when we can spend some time to update cayenne).

    This morning I think I found a solution which seems to work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    ObjectContext context = object.getObjectContext();
    if (context instanceof DataContext) {
    DataContext dataContext = (DataContext)context;
    QueryCache cache = dataContext.getParentDataDomain().getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    }

    Is this acceptable (at least .. waiting for our update to cayenne) ?

    Regards
    Francesco Romano
    On Aug 21, 2012, at 6:36 PM, Francesco Romano wrote:
    Hi everybody.

    I'm trying to add caching support (query cache) to a project which uses cayenne.
    For what I understood in the online documentation there are two types of caches: local and shared.
    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache.

    Now... the problem.. I have a query cached (a sort of select * from table) and a new row is added in the table. I would like that the next time the same query is called also the new row is fetched.

    This is the query cache

    SelectQuery select = new SelectQuery(t);
    Class t; //this is the class of the persistent object to be fetched
    select.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);

    select.setCacheGroups(t.getName());

    This is my "sample" test code (Network is a Cayenne Object class) (GetAllNetwork is a selectquery with the above caching. AddNetwork adds a new object and commit it. A new DataContext is used every time)

    List<Network> networks = dbHandle.GetAllNetwork();
    Network net = dbHandle.AddNetwork();
    List<Network> newNetworks = dbHandle.GetAllNetwork();

    assertEquals(networks.size() + 1, newNetworks.size());


    Now... my assert is not true, because the query is cached.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }

    Any help?

    Thanks
    Regards

    Francesco Romano
  • Andrus Adamchik at Aug 22, 2012 at 1:20 pm
    Is this acceptable (at least .. waiting for our update to cayenne) ?
    Yep. See my other message. We both guessed the cause of the issue simultaneously :)

    Andrus


    On Aug 22, 2012, at 4:12 PM, Francesco Romano wrote:
    On Aug 22, 2012, at 3:04 PM, Andrus Adamchik wrote:

    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache. Correct.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    This is going in the right direction. So is listener method invoked, but the cache is not cleared, or the listener method is never invoked.

    BTW Cayenne 3.1 has a nice set of extensions called cayenne-lifecycle. The docs are still sparse (we are working on those), but there is a @CacheGroups annotation placed on persistent classes that tells Cayenne that any changes to a given type of objects should generate a cache invalidation event. E.g.:

    @CacheGroups("news")
    public class News extends com.foo.auto._News { }

    processing of this annotation is enabled by installing org.apache.cayenne.lifecycle.cache.CacheInvalidationFilter (also part of cayenne-lifecycle):

    DataChannelFilter filter = new CacheInvalidationFilter();

    CayenneRuntime runtime = ...

    // a bit clunky.. may merge the following 2 lines in one in the future releases:
    runtime.getDataDomain().addFilter(filter);
    runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(filter);

    Cheers,
    Andrus
    Thank you for your answer.
    I don't think we can update our cayenne right now, but we will take a look at the annotations asap (it means: when we can spend some time to update cayenne).

    This morning I think I found a solution which seems to work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    ObjectContext context = object.getObjectContext();
    if (context instanceof DataContext) {
    DataContext dataContext = (DataContext)context;
    QueryCache cache = dataContext.getParentDataDomain().getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    }

    Is this acceptable (at least .. waiting for our update to cayenne) ?

    Regards
    Francesco Romano
    On Aug 21, 2012, at 6:36 PM, Francesco Romano wrote:
    Hi everybody.

    I'm trying to add caching support (query cache) to a project which uses cayenne.
    For what I understood in the online documentation there are two types of caches: local and shared.
    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache.

    Now... the problem.. I have a query cached (a sort of select * from table) and a new row is added in the table. I would like that the next time the same query is called also the new row is fetched.

    This is the query cache

    SelectQuery select = new SelectQuery(t);
    Class t; //this is the class of the persistent object to be fetched
    select.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);

    select.setCacheGroups(t.getName());

    This is my "sample" test code (Network is a Cayenne Object class) (GetAllNetwork is a selectquery with the above caching. AddNetwork adds a new object and commit it. A new DataContext is used every time)

    List<Network> networks = dbHandle.GetAllNetwork();
    Network net = dbHandle.AddNetwork();
    List<Network> newNetworks = dbHandle.GetAllNetwork();

    assertEquals(networks.size() + 1, newNetworks.size());


    Now... my assert is not true, because the query is cached.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }

    Any help?

    Thanks
    Regards

    Francesco Romano
  • Francesco Romano at Aug 22, 2012 at 1:25 pm
    :)
    Thank you very much

    Francesco
    On Aug 22, 2012, at 3:20 PM, Andrus Adamchik wrote:

    Is this acceptable (at least .. waiting for our update to cayenne) ?
    Yep. See my other message. We both guessed the cause of the issue simultaneously :)

    Andrus


    On Aug 22, 2012, at 4:12 PM, Francesco Romano wrote:
    On Aug 22, 2012, at 3:04 PM, Andrus Adamchik wrote:

    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache. Correct.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    This is going in the right direction. So is listener method invoked, but the cache is not cleared, or the listener method is never invoked.

    BTW Cayenne 3.1 has a nice set of extensions called cayenne-lifecycle. The docs are still sparse (we are working on those), but there is a @CacheGroups annotation placed on persistent classes that tells Cayenne that any changes to a given type of objects should generate a cache invalidation event. E.g.:

    @CacheGroups("news")
    public class News extends com.foo.auto._News { }

    processing of this annotation is enabled by installing org.apache.cayenne.lifecycle.cache.CacheInvalidationFilter (also part of cayenne-lifecycle):

    DataChannelFilter filter = new CacheInvalidationFilter();

    CayenneRuntime runtime = ...

    // a bit clunky.. may merge the following 2 lines in one in the future releases:
    runtime.getDataDomain().addFilter(filter);
    runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(filter);

    Cheers,
    Andrus
    Thank you for your answer.
    I don't think we can update our cayenne right now, but we will take a look at the annotations asap (it means: when we can spend some time to update cayenne).

    This morning I think I found a solution which seems to work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    ObjectContext context = object.getObjectContext();
    if (context instanceof DataContext) {
    DataContext dataContext = (DataContext)context;
    QueryCache cache = dataContext.getParentDataDomain().getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }
    }

    Is this acceptable (at least .. waiting for our update to cayenne) ?

    Regards
    Francesco Romano
    On Aug 21, 2012, at 6:36 PM, Francesco Romano wrote:
    Hi everybody.

    I'm trying to add caching support (query cache) to a project which uses cayenne.
    For what I understood in the online documentation there are two types of caches: local and shared.
    Local cache is local to a data context (right?). But currently the application creates a new datacontext for every "transaction", so if I understood correctly the local cache is useless and I should use the shared cache.

    Now... the problem.. I have a query cached (a sort of select * from table) and a new row is added in the table. I would like that the next time the same query is called also the new row is fetched.

    This is the query cache

    SelectQuery select = new SelectQuery(t);
    Class t; //this is the class of the persistent object to be fetched
    select.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE);

    select.setCacheGroups(t.getName());

    This is my "sample" test code (Network is a Cayenne Object class) (GetAllNetwork is a selectquery with the above caching. AddNetwork adds a new object and commit it. A new DataContext is used every time)

    List<Network> networks = dbHandle.GetAllNetwork();
    Network net = dbHandle.AddNetwork();
    List<Network> newNetworks = dbHandle.GetAllNetwork();

    assertEquals(networks.size() + 1, newNetworks.size());


    Now... my assert is not true, because the query is cached.
    I also tried to add a listener (on postPersist, postUpdate and postRemove) to clear the cache for that particular group, but it does not work:

    private void clearCache(Object entity) {
    Persistent object = (Persistent)entity;
    QueryCache cache = ((BaseContext)object.getObjectContext()).getQueryCache();
    cache.removeGroup(object.getClass().getName());
    }

    Any help?

    Thanks
    Regards

    Francesco Romano

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupuser @
categoriescayenne
postedAug 21, '12 at 3:37p
activeAug 22, '12 at 1:25p
posts6
users2
websitecayenne.apache.org

People

Translate

site design / logo © 2022 Grokbase