I'm trying to configure ehcache with openjpa. I get the following error:
org.apache.openjpa.lib.util.ParseException:
Instantiation of plugin "DataCacheManager" with value "ehcache" caused an error
"java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: ehcache".
The alias or class name may have been misspelled, or the class may not have be available in the class path.
Valid aliases for this plugin are: [default]
here's my excerpt from persistence.xml:
<property name="openjpa.QueryCache" value="ehcache" />
<property name="openjpa.DataCacheManager" value="ehcache" />
here's my ehcache.xml:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<!-- -->
<cache name="openjpa" maxElementsInMemory="10000"
maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="300"
timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU"
transactionalMode="on" />
</ehcache>
And here's my pom.xml plugin dependency:
net.sf.ehcache
ehcache-openjpa
0.2.0
Is there any other way to configure openjpa+ehcache?
Yes it should work. Make sure that the ehcache-openjpa jar is on your classpath. I know this is slightly more complicated if you are running in a container environment(ie: WAS).
[update]
I know I had this working at one point and I had to do something funny with WAS shared libraries to get this to work, but I can't find any of my notes. I vaugely recollect that the problem had to do with OpenJPA not detecting Ehcache at start up, in turn we didn't register the 'ehcache' aliases.
Try configuring OpenJPA with the following properties :
<property name="openjpa.QueryCache" value="net.sf.ehcache.openjpa.datacache.EhCacheQueryCache"/>
<property name="openjpa.DataCacheManager" value="net.sf.ehcache.openjpa.datacache.EhCacheDataCacheManager"/>
<property name="openjpa.DataCache" value="net.sf.ehcache.openjpa.datacache.EhCacheDataCache"/>
<property name="openjpa.RemoteCommitProvider" value="net.sf.ehcache.openjpa.datacache.NoOpRemoteCommitProvider"/>
[/update]
Related
I'm integrating Caching into my web application but for some reason Application Context failed to load when adding the #Cacheable annotation.
I have been trying to solve the issue for two days now, your help is really appreciated!
app.context.xml
<cache:annotation-driven cache-manager="EhCacheManagerBean" key-generator="customKeyGenerator" />
<bean id="EhCacheManagerBean" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheBean" />
<bean id="ehcacheBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:EhCache.xml" p:shared="true" />
<bean id ="customKeyGenerator" class="com.app.site.v2.cache.customKeyGenerator"/>
<bean id="siteService" class="com.app.site.v2.SiteService" primary="true"/>
EhCache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cache name="cacheSite"
maxEntriesLocalHeap="100"
maxEntriesLocalDisk="1000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
Method that is being cached
public class SiteService implements ISiteService {
#Cacheable("cacheSite")
public JsonObject getSiteJson(String siteId, boolean istTranslated) { ... }
}
Exception that is being thrown
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'siteService' is expected to be of type 'com.app.site.v2.SiteService' but was actually of type 'com.sun.proxy.$Proxy57'
The comment of #yegdom is actually the right answer. When adding the Cacheable annotation, Spring generates a proxy which implements ISiteService. And somewhere in your code, you have a bean requiring SiteService, the implementation.
There are three solutions (in preference order):
Remove the useless interface... A single implementation is just adding complexity for no direct benefit. Removing it will force Spring to use a class proxy
Fix your dependency to use ISiteService
Add proxy-target-class="true" to cache:annotation-driven to tell Spring to create a class proxy
I really do not recommend the last one since you should always depend on the interface or always depend on the class (and delete the interface). Not both at the same time.
I want to use ehcache in my spring mvc web application.because my server reset every day so i want caching be permanent. do i save it in hard path? and hoe save it?
thanks.
in my dispatcher-servlet.xml i add this
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"/>
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
<property name="shared" value="true"/>
</bean>
and my ehcach.xml is
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="c:/tmp"/>
<defaultCache
maxElementsInMemory="500" eternal="true" overflowToDisk="false" memoryStoreEvictionPolicy="LFU"/>
<cache name="mycache"
maxElementsInMemory="0"
eternal="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="1200"
memoryStoreEvictionPolicy="LRU">
[1] <persistence strategy="localRestartable" synchronousWrites="false" />
</cache>
i add this [1] until caching be permanent and after server reset not be remove.but this exception occur Element does not allow nested elements.
also i use ehcach-core2.7.0.jar
Element <cache> does not allow nested <persistence> elements.
You should not mix legacy configuration options - attributes diskPersistent and overflowToDisk on the cache element with recommended persistence element.
However, to get to the open source disk persistent setting, you need to stick with the legacy options.
So your configuration should drop the persistence element to become:
<cache name="mycache"
maxElementsInMemory="0"
eternal="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="1200"
memoryStoreEvictionPolicy="LRU">
</cache>
However, you should also give a meaningful value to maxElementsInMemory, so you can have a hot set of entries for which you do not need to pay the deserialization price when accessing them.
You also need to decide if you want eternal elements or have expiration. For this, remove either eternal="true" or the timeToLiveSeconds and timeToIdleSeconds pair. Having both is not an error in Ehcache for compatibility reasons, but makes it hard to know what you intended initially.
And as a last advice, I would move the cache content to a folder with a more descriptive name instead of c:/tmp.
Note that the open source disk persistent tier is not fault tolerant, so improper shutdown of the Cache or CacheManager or exceptions while doing IO can corrupt the data. If that happens, you will have to clear the data folder before you can restart your cache.
For more details, see the Ehcache 2.7 persistence documentation.
Have you tried this?
<cache eternal="true"
maxElementsInMemory="0"
name="<cache name>"
overflowToDisk="true"/>
I'm using SecondLevelCache with hibernate. This is my xml configuration file:
<persistence-unit name="EntityTestHibernate" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/DB_NAME"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.username" value="USERNAME"/>
<property name="hibernate.connection.password" value="PASSWORD"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />
My ehcache.xml:
<ehcache name="cacheTest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<defaultCache eternal="true" maxElementsInMemory="100" overflowToDisk="false" />
<cache name="entityCache"
maxEntriesLocalHeap="50"
eternal="false"
timeToLiveSeconds="120"
/>
</ehcache>
and on my entity there is an annotation like this
#Cache(region="entityCache", usage=CacheConcurrencyStrategy.READ_WRITE )
When i run locally my UnitTest i have no problems. All tests passed, but if i run tests on my Hudson continuos integretion i have following error (problem is same if i set or not annotation on it #DirtiesContext):
> javax.persistence.PersistenceException: org.hibernate.cache.CacheException: java.lang.IllegalStateException:
> The cacheTest Cache is not alive (STATUS_SHUTDOWN) at
> org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1167)
> at
> org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:673)
> at
> org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:641)
> Caused by: org.hibernate.cache.CacheException:
> java.lang.IllegalStateException: The cacheTest Cache is not alive
> (STATUS_SHUTDOWN) at
> net.sf.ehcache.hibernate.regions.EhcacheTransactionalDataRegion.remove(EhcacheTransactionalDataRegion.java:164)
> at
> net.sf.ehcache.hibernate.strategy.AbstractEhcacheAccessStrategy.evict(AbstractEhcacheAccessStrategy.java:119)
> at
> net.sf.ehcache.hibernate.nonstop.NonstopAwareEntityRegionAccessStrategy.evict(NonstopAwareEntityRegionAccessStrategy.java:96)
> at
> org.hibernate.event.def.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:144)
> at
> org.hibernate.event.def.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:62)
> at org.hibernate.impl.SessionImpl.fireRefresh(SessionImpl.java:1118)
> at org.hibernate.impl.SessionImpl.refresh(SessionImpl.java:1098) at
> org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:666)
> Caused by: java.lang.IllegalStateException: The cacheTest Cache is
> not alive (STATUS_SHUTDOWN) at
> net.sf.ehcache.Cache$CacheStatus.checkAlive(Cache.java:3946) at
> net.sf.ehcache.Cache.checkStatus(Cache.java:2664) at
> net.sf.ehcache.Cache.removeInternal(Cache.java:2288) at
> net.sf.ehcache.Cache.remove(Cache.java:2207) at
> net.sf.ehcache.Cache.remove(Cache.java:2125) at
> net.sf.ehcache.hibernate.regions.EhcacheTransactionalDataRegion.remove(EhcacheTransactionalDataRegion.java:160)
How could i solve that problem?
Why that happens only on Hudson?
UPDATE
As suggested by #lanimall i have:
disabled all nodes on Hudson;
modified persistence.xml.
Replacing
< property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />
with
<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory" />
but that doesn't solve my problem (but it's a good starting :-)...error is same).
My environment configuration is hibernate3 and ehcache-2.7.2
what version of hibernate are you using? and Ehcache?
I think what could be happening is that hudson is running on some application server (such as Glassfish, Tomcat 5, JBoss, Jetty 6, etc) and it might have either some ehcache or hibernate lib versions that are competing with the ones you're embedding in your app...hence the problem happening only when running tests in hudson. Make sure to look into that...
Also, per ehcache/hibernate documentation (http://ehcache.org/documentation/user-guide/hibernate#Configure-Ehcache-as-the-Second-Level-Cache-Provider), please try to use the "hibernate.cache.region.factory_class" setting as opposed to the "hibernate.cache.provider_class"...
And I also usually use the singleton factory (otherwise your JUNIT tests will not work...). Based on hibernate version, use
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
or (for hibernate 4.x and above)
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hope that helps...
I have found solution!
In my persistence.xml i had 2 persistence-unit configured as Singleton and in some tests were used both. In that way those share EhCacheSingleton.
Then happens that when EntityFactory associated to one of that was shutdown, consequently make a ehcache shutdown that was used by the other one (because there is one instance of Singleton shared between those 2 entity manager).
Many thanks to #lanimall to open my mind!
JUnit share Spring context for speed. I've avoid from this exception when remove explicitly Spring context closing in one of my test.
I have an application in which I use spring 3.0.2 and ibatis. Now, I need to integrate ehcache with my code. I tried this link but couldnt get it working. I would prefer someone to give me the details of the jars required, xml configurations to be done and code changes if required.
Upgrade to the latest spring 3.1 milestone - it has built-in cache support through annotations - see here
Apart from that, you can always use the EhCacheFactoryBean
To implement this in your application, follow these steps:
Step 1:
Add the jars to your application as listed on the Ehcache Annotations for Spring project site.
Step 2:
Add the Annotation to methods you would like to cache. Lets assume you are using the Dog getDog(String name) method from above:
#Cacheable(name="getDog")
Dog getDog(String name)
{
....
}
Step 3:
Configure Spring. You must add the following to your Spring configuration file in the beans declaration section:
<ehcache:annotation-driven cache-manager="ehCacheManager" />
Please refer to Ehcache site for complete details.
To integrate Ehcache just follow below steps
1 - Add Dependency in pom XML file
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.9</version>
</dependency>
2 - create an xml file called spring-cache.xml put it in the resources folder
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache" />
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
</beans>
3 - as you can see we are using reference of ehcache.xml so create file and put it in resources folder
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<cache name="users" maxEntriesLocalHeap="5000"
maxEntriesLocalDisk="1000" eternal="false" diskSpoolBufferSizeMB="20"
timeToIdleSeconds="200" timeToLiveSeconds="500"
memoryStoreEvictionPolicy="LFU" transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
so can see create a cache for "users" so that can use wherever user list is queried from the database
4 - use it like below code
#Cacheable(value="users")
public List<User> userList() {
return userDao.findAll();
}
so that's it the same way you can implement cache wherever is required
still have some doubt or confusion see live demo
Integrate EhCache in Spring MVC
Hi I've run into some problems with hibernate 2nd level cache.
As cache provider I use ehcache.
Part of config from persistence.xml
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />
<property name="hibernate.cache.provider_configuration_file_resource_path" value="/ehcache.xml" />
I configure my entities using annotations so:
#Cache(region = "Kierunek", usage = CacheConcurrencyStrategy.READ_WRITE)
public class Kierunek implements Serializable {
imports for those annotations are:
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
my ehcache.xml
<diskStore path="java.io.tmpdir" />
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cache name="Kierunek" maxElementsInMemory="1000"
eternal="true" overflowToDisk="false" memoryStoreEvictionPolicy="LRU" />
And anyone idea why i get following error ?
WARNING: Could not find a specific ehcache configuration for cache named [persistence.unit:unitName=pz2EAR.ear/pz2EJB.jar#pz2EJB.Kierunek]; using defaults.
19:52:57,313 ERROR [AbstractKernelController] Error installing to Start: name=persistence.unit:unitName=pz2EAR.ear/pz2EJB.jar#pz2EJB state=Create
java.lang.IllegalArgumentException: Cache name cannot contain '/' characters.
solution is to add another property to persistence.xml
<property name="hibernate.cache.region_prefix" value=""/>
and that removes that faulty prefix big thx ruslan!
IMHO, you get the generated region name for your class. This generated name "persistence.unit:unitName=pz2EAR.ear/pz2EJB.jar#pz2EJB.pl.bdsdev.seps.encje.Kierunek". And it's not defined in your's ehcache.xml configuration. Also it's looking for the predefined name, so it can't use default region.
As an option to solve this problem you can use #Cache annotation properties to predefine some region name, like
#Cache(region = 'Kierunek', usage = CacheConcurrencyStrategy.READ_WRITE)
public class Kierunek implements Serializable {
// ....
}
And in ehcache.xml
<cache name="Kierunek"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU" />
Hibernate add prefix to cache names based on appname or value of property hibernate.cache.region_prefix
If You set this property for "" (empty string) then You have regions named exactly like name in hibernate config.
EHCache needs a configuration that tells it how to cache the objects in your application (live time, cache type, cache size, caching behaviour etc). For every class you try to cache it will try to find an appropriate cache configuration and print the error above if it fails to do so.
See http://ehcache.sourceforge.net/documentation/configuration.html for how to configure EHCache.