You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Andrus Adamchik <an...@objectstyle.org> on 2016/07/01 01:23:17 UTC

Re: QueryCache injection problem with multiple runtimes

Hi John,

> runtime.getDataDomain().setQueryCache(queryCache);
> But this actually does *nothing*.  The DataContextFactory uses the
> QueryCache that was set by the injector and ignores this later
> modification.  This method should be removed or even better - made to work.

This method actually works in a sense that it provides a QC for the DataDomain instance (shared cache).

> Caused by: net.sf.ehcache.CacheException: *Another CacheManager with same
> name 'MyCache' already exists in the same VM. Please provide unique names
> for each CacheManager in the config or do one of following:*

Hmm... Can't find 'assertNoCacheManagerExistsWithSameName' in my version of EhCache (2.4.3 that we test Cayenne against). What version are you on? I'd like to find out where the name is coming from. If you can e.g. set it in constructor, then you can simply do something like this:

Module m1 = (binder) -> binder.bind(QueryCache.class).toInstance(new EhCacheQueryCache("name1"));
Module m2 = (binder) -> binder.bind(QueryCache.class).toInstance(new EhCacheQueryCache("name2"));

Andrus


> On Jun 23, 2016, at 6:03 PM, John Huss <jo...@gmail.com> wrote:
> 
> I'm starting to use QueryCache for the first time, and I'm using EhCache
> since OSCache is a dead product.  My app creates two separate runtimes that
> are identical, but separate.  If I configure both to use EhCache with the
> module:
> public class AppModule  {
> public void configure(Binder binder) {
> binder.bind(QueryCache.class).to(EhCacheQueryCache.class);
>        }
> }
> 
> then the app fails to start because the cache can't be created twice with
> the same name (see below).
> 
> I thought I could ditch the injection and just set it directly:
> 
> runtime.getDataDomain().setQueryCache(queryCache);
> But this actually does *nothing*.  The DataContextFactory uses the
> QueryCache that was set by the injector and ignores this later
> modification.  This method should be removed or even better - made to work.
> 
> org.apache.cayenne.di.DIRuntimeException: Error instantiating class
> 'org.apache.cayenne.cache.EhCacheQueryCache'
> at
> org.apache.cayenne.di.spi.ConstructorInjectingProvider.get(ConstructorInjectingProvider.java:144)
> ...
> Caused by: net.sf.ehcache.CacheException: *Another CacheManager with same
> name 'MyCache' already exists in the same VM. Please provide unique names
> for each CacheManager in the config or do one of following:*
> *1. Use one of the CacheManager.create() static factory methods to reuse
> same CacheManager with same name or create one if necessary*
> 2. Shutdown the earlier cacheManager before creating new one with same name.
> The source of the existing CacheManager is: DefaultConfigurationSource [
> ehcache.xml or ehcache-failsafe.xml ]
> at
> net.sf.ehcache.CacheManager.assertNoCacheManagerExistsWithSameName(CacheManager.java:628)
> at net.sf.ehcache.CacheManager.init(CacheManager.java:392)
> at net.sf.ehcache.CacheManager.<init>(CacheManager.java:375)
> at
> org.apache.cayenne.cache.EhCacheQueryCache.<init>(EhCacheQueryCache.java:46)
> ... 32 more
> 
> 
> 
> If I change the EhCacheQueryCache to follow the suggestion in the error it
> looks like this:
>    public MyEhCacheQueryCache() {
>        cacheManager = CacheManager.getInstance();
>        init();
>    }
> 
> This fixes the problem, but I'm not sure it's the right behavior.  This
> will result in the same query cache instance being shared among all the
> runtimes, which I'm guessing isn't how it is supposed to work.
> 
> John


Re: QueryCache injection problem with multiple runtimes

Posted by Andrus Adamchik <an...@objectstyle.org>.
> On Jun 30, 2016, at 9:23 PM, Andrus Adamchik <an...@objectstyle.org> wrote:
> 
> 
> Module m1 = (binder) -> binder.bind(QueryCache.class).toInstance(new EhCacheQueryCache("name1"));
> Module m2 = (binder) -> binder.bind(QueryCache.class).toInstance(new EhCacheQueryCache("name2"));

Or rather 

  new EhCacheQueryCache(new CacheManager("name2")); 

etc. Which of course is still pseudo code, as I have no idea whether you can explicitly pass a name to CM.

Andrus