ehcache / ehcache3

Ehcache 3.x line
http://www.ehcache.org
Apache License 2.0
2.01k stars 579 forks source link

Spring 4.3.7 and ehcache 3.3.1 can't autowire cache manager #1994

Closed chandrasekhar4u closed 7 years ago

chandrasekhar4u commented 7 years ago

I am using Spring boot 1.5.2.RELEASE, Spring 4.3.7, ehcache 3.3.1 in my application,

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns='http://www.ehcache.org/v3' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
    xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
                            http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">
    <service>
        <jsr107:defaults default-template="maxEntriesOnHeapCache"
            enable-management="false" enable-statistics="true">
            <jsr107:cache name="mayCache1" template="heap-cache" />
            <jsr107:cache name="mayCache2" template="heap-cache" />
            <jsr107:cache name="mayCache3" template="heap-cache" />
        </jsr107:defaults>
    </service>

    <cache-template name="maxEntriesOnHeapCache">
        <heap unit="entries">2000</heap>
    </cache-template>

    <cache-template name="heap-cache">
        <listeners>
            <listener>
                <class>com.myCompany.CacheEventLogger</class>
                <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
                <event-ordering-mode>UNORDERED</event-ordering-mode>
                <events-to-fire-on>CREATED</events-to-fire-on>
                <events-to-fire-on>UPDATED</events-to-fire-on>
                <events-to-fire-on>EXPIRED</events-to-fire-on>
                <events-to-fire-on>REMOVED</events-to-fire-on>
                <events-to-fire-on>EVICTED</events-to-fire-on>
            </listener>
        </listeners>
        <resources>
            <heap unit="entries">10000</heap>
            <offheap unit="MB">100</offheap> <!-- unit of measure is case sensitive! -->
        </resources>
    </cache-template>
</config>

application.properties

spring.cache.jcache.config=classpath:ehcache.xml spring.cache.cache-names=mayCache1,mayCache2,mayCache3 spring.cache.caffeine.spec=maximumSize=1000,expireAfterAccess=600s

pom.xml dependencies:

        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
                        <version>1.0.0</version>
        </dependency>

        <!-- Added for cache ehcache  -->
        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>3.3.1</version>
        </dependency>

When I try to access cache manager in CacheConfiguration class it's throwing error like below:

Unsatisfied dependency expressed through field 'cacheManager'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cache.CacheManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

While debugging I observed that EhCacheCacheManager is getting called and trying to autowire net.sf.ehcache.CacheManager cacheManager from it. I am not able to understand why spring 4.3.x has old version of CacheManager instance of Ehcache, and not able to inject/autowire object. Please help me to solve this issue.

henri-tremblay commented 7 years ago

Please use StackOverflow or our mailing list to ask such questions.

Spring supports Ehcache 2 and 3. The EhCacheCacheManager is used for Ehcache 2. You should not use it. Ehcache 3 is configured through JCache so you should use the JCacheCacheManager instead.

Have a look here to see an example.

chandrasekhar4u commented 7 years ago

If I used ehcache.xml in the application still I need to programatically create cache manager bean and need to create cache objects?

anthonydahanne commented 7 years ago

@chandrasekhar4u you can use either jsr-107 api or ehcache3 api to load an ehcache.xml and retrieve your CacheManager and Caches from it : http://www.ehcache.org/documentation/3.3/getting-started.html http://www.ehcache.org/documentation/3.3/107.html

henri-tremblay commented 7 years ago

To use only configuration you can do something similar to:

application.properties

spring.cache.jcache.config=ehcache.xml

App.java:

@SpringBootApplication
@EnableCaching
public class App 
{
    public static void main( String[] args ) throws Exception {
        SpringApplication.run(App.class, args);
    }
}

Assuming you have spring-boot-starter-cache as a dependency.

The JCacheCacheConfiguration class will magically retrieve the ehcache.xml using the property and seeing the Ehcache is the JCache provider, initialize everything correctly.

chandrasekhar4u commented 7 years ago

@henri-tremblay Thank you for the reply,

I tried the same, and I autowired cacheManager in one of my spring service. While application deployment I can see cache is getting loaded, but when I try to access pages, it's showing error Unsatisfied dependency expressed through field 'cacheManager'.

How can I access cacheManager and cache objects from it? (how application will come to know which cache manager implementation to invoke?)

henri-tremblay commented 7 years ago

You can use @Cacheable annotation to cache a method. But autowiring should work. Make sure you are autowiring the spring cache manager (org.springframework.cache.CacheManager), not the Ehcache one.

If that's already the case, I would need a full stack trace to help you.

amirensit commented 4 years ago

That's the key for me:

Make sure you are autowiring the spring cache manager (org.springframework.cache.CacheManager)

Thanks @henri-tremblay.