For JDK1.4 and JDK5, ehcache requires commons-logging
and commons-collections
3.1 from Apache's Jakarta project. The commons-collections
library provided in hibernate is 2.1, so you will need to upgrade it if
working with Hibernate.
For JDK1.2 and JDK
1.3, ehcache also requires Apache xerces
(xml-apis.jar and xercesImpl.jar), version 2.5.
The dependencies are also Hibernate dependencies, so if you are
using ehcache as a Hibernate plugin, dependency requirements are met.
ehcache consists
of a CacheManager
, which manages caches. Caches contain
elements,
which are essentially name value pairs. Caches are physically
implemented either in-memory, or on disk.
CacheManager
. You may only have one CacheManager
per class loader, as
it expects to be a singleton. If an application has more than one,
ensure a separate configuration file is used for each. Otherwise disk
caches will conflict.MemoryStore
. Optionally
they also
overflow
to a DiskStore
.
The MemoryStore
is
always enabled. It is not directly manipulated, but is a component of
every cache.MemoryStore
for JDK1.4 and JDK 5 it is backed by an extended LinkedHashMap.
This provides a combined linked list and a hash map, and is ideally
suited for caching. Using this standard Java class simplifies the
implementation of the memory cache. It directly supports
obtaining the least recently used element.Benchmark |
ehcache |
JCS | Difference |
---|---|---|---|
insert 5 million typical
CacheElements. Then get each of them by key. |
22.704s |
42.176s |
79% faster |
insert 5,000,000 typical
CacheElements and get each of them by key. Then remove them one at a
time by key |
14.999s |
44.536s |
293% faster |
MemoryStore
.
See calculateInMemorySize().
It returns the serialized size of the cache. Do not use this method in
production. It is very slow. It is only meant to provide a rough
estimate. maxElementsInMemory
.
The disk cache
provides a disk spooling facility.DiskStore
is configured to be persistent, a "cache
name.index" file is also created.diskExpiryThreadIntervalSeconds
sets the interval between runs of the expiry thread. Warning: setting this to a low value
is not recommended. It can cause excessive DiskStore
locking and high cpu utilisation. The default value is 120 seconds.
DiskStore
. A NotSerializableException
will be thrown if the object is not serializable.
DiskStore
s are thread safe. DiskStore
persistence is controlled
by the diskPersistent configuration
element. If false or omitted, DiskStore
s will not persist
between
CacheManager
restarts. The data file for each cache will
be deleted,
if it
exists, both on shutdown and startup. No data from a previous instance
CacheManager
is available.CacheManager
. This CacheManager
may be in the same
VM instance, or a new one.DiskStore
.
This happens when the CacheManager is shut down, a Cache is disposed,
or the VM is being shut down. It is recommended that the
CacheManager shutdown()
method be used. See Virtual Machine Shutdown
Considerations for guidance on how to safely shut the Virtual
Machine down.DiskStore
is persisted, the following steps take
place:MemoryStore
are
flushed to the
DiskStoreDiskStore
starts with no Elements in it. DiskStore
starts. All data is available.MemoryStore
and a DiskStore
. The MemoryStore
is
approximately
an order of magnitude faster than the DiskStore
. The
reason is that
the DiskStore
incurs the following extra overhead:
MemoryStore
using an LRU
algorithm A Cache should alway have its maximumSize
attribute
set to 1 or higher. A Cache with a maximum
size of 1 has twice the performance of a disk only cache, i.e. one
where the maximumSize
is
set to 0. For this reason a warning will be issued if a Cache is
created with a 0 maximumSize
.
CacheManager
via an EJB session bean. CacheManager
can access Cache
s and
Elements. Elements are serializable
. and can be sent over
a network using RMI or another protocol. kill -SIGTERM pid
or kill -15 pid
on
Unix
systems.kill -SIGKILL pid
or kill -9 pid
TerminateProcess
call is
sent to the process on Windows systems.SimpleLog
. This enables
ehcache to use logging infrastructures compatible with Java versions
from JDK1.2 to JDK5. It does create a dependency on Apache Commons
Logging, however many projects, including Hibernate, share the same
dependency.WARN
level in log4J
and the WARNING
level for JDK1.4 logging. 1. cvs
-d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ehcache login 2. cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ehcache co ehcache |
DiskStore
s are to be
created. (diskStore
element)<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="ehcache"> <xs:complexType> <xs:sequence> <xs:element ref="diskStore"/> <xs:element ref="defaultCache"/> <xs:element maxOccurs="unbounded" ref="cache"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="diskStore"> <xs:complexType> <xs:attribute name="path" use="required" type="xs:NCName"/> </xs:complexType> </xs:element> <xs:element name="defaultCache"> <xs:complexType> <xs:attribute name="eternal" use="required" type="xs:boolean"/> <xs:attribute name="maxElementsInMemory" use="required" type="xs:integer"/> <xs:attribute name="overflowToDisk" use="required" type="xs:boolean"/> <xs:attribute name="timeToIdleSeconds" use="optional" type="xs:integer"/> <xs:attribute name="timeToLiveSeconds" use="optional" type="xs:integer"/> <xs:attribute name="diskPersistent" use="optional" type="xs:integer"/> <xs:attribute name="diskExpiryThreadIntervalSeconds" use="optional" type="xs:integer"/> </xs:complexType> </xs:element> <xs:element name="cache"> <xs:complexType> <xs:attribute name="eternal" use="required" type="xs:boolean"/> <xs:attribute name="maxElementsInMemory" use="required" type="xs:integer"/> <xs:attribute name="name" use="required" type="xs:NCName"/> <xs:attribute name="overflowToDisk" use="required" type="xs:boolean"/> <xs:attribute name="timeToIdleSeconds" use="optional" type="xs:integer"/> <xs:attribute name="timeToLiveSeconds" use="optional" type="xs:integer"/> <xs:attribute name="diskPersistent" use="optional" type="xs:integer"/> <xs:attribute name="diskExpiryThreadIntervalSeconds" use="optional" type="xs:integer"/> </xs:complexType> </xs:element> </xs:schema> |
user.home - User's home
directory user.dir - User's current working directory java.io.tmpdir - Default temporary directory |
<ehcache> <!-- Sets the path to the directory where cache .data files are created. If the path is a Java System Property it is replaced by its value in the running VM. The following properties are translated: user.home - User's home directory user.dir - User's current working directory java.io.tmpdir - Default temp file path --> <diskStore path="java.io.tmpdir"/> <!--Default Cache configuration. These will applied to caches programmatically created through the CacheManager. The following attributes are required: maxElementsInMemory - Sets the maximum number of objects that will be created in memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. The following attributes are optional: timeToIdleSeconds - Sets the time to idle for an element before it expires. i.e. The maximum amount of time between accesses before an element expires Is only used if the element is not eternal. Optional attribute. A value of 0 means that an Element can idle for infinity. The default value is 0. timeToLiveSeconds - Sets the time to live for an element before it expires. i.e. The maximum time between creation time and when an element expires. Is only used if the element is not eternal. Optional attribute. A value of 0 means that and Element can live for infinity. The default value is 0. diskPersistent - Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value is 120 seconds. --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> <!--Predefined caches. Add your cache configuration settings here. If you do not have a configuration for your cache a WARNING will be issued when the CacheManager starts The following attributes are required: name - Sets the name of the cache. This is used to identify the cache. It must be unique. maxElementsInMemory - Sets the maximum number of objects that will be created in memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. The following attributes are optional: timeToIdleSeconds - Sets the time to idle for an element before it expires. i.e. The maximum amount of time between accesses before an element expires Is only used if the element is not eternal. Optional attribute. A value of 0 means that an Element can idle for infinity. The default value is 0. timeToLiveSeconds - Sets the time to live for an element before it expires. i.e. The maximum time between creation time and when an element expires. Is only used if the element is not eternal. Optional attribute. A value of 0 means that and Element can live for infinity. The default value is 0. diskPersistent - Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value is 120 seconds. --> <!-- Sample cache named sampleCache1 This cache contains a maximum in memory of 10000 elements, and will expire an element if it is idle for more than 5 minutes and lives for more than 10 minutes. If there are more than 10000 elements it will overflow to the disk cache, which in this configuration will go to wherever java.io.tmp is defined on your system. On a standard Linux system this will be /tmp" --> <cache name="sampleCache1" maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" /> <!-- Sample cache named sampleCache2 This cache has a maximum of 1000 elements in memory. There is no overflow to disk, so 1000 is also the maximum cache size. Note that when a cache is eternal, timeToLive and timeToIdle are not used and do not need to be specified --> <cache name="sampleCache2" maxElementsInMemory="1000" eternal="true" overflowToDisk="false" /> <!-- Sample cache named sampleCache3. This cache overflows to disk. The disk store is persistent between cache and VM restarts. The disk expiry thread interval is set to 10 minutes, overriding the default of 2 minutes. --> <cache name="sampleCache3" maxElementsInMemory="500" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" diskPersistent="true" diskExpiryThreadIntervalSeconds="1" /> <!-- Place configuration for your caches following --> </ehcache> |
DiskStore
path attribute to the value given by the Java system property
"java.io.tmpdir"
(/tmp on Unix-like systems) and sets the default cache to reasonable
values. ehcache-failsafe.xml is reproduced here:<ehcache> <!-- Sets the path to the directory where cache .data files are created. If the path is a Java System Property it is replaced by its value in the running VM. The following properties are translated: user.home - User's home directory user.dir - User's current working directory java.io.tmpdir - Default temp file path --> <diskStore path="java.io.tmpdir"/> <!--Default Cache configuration. These will applied to caches programmatically created through the CacheManager. The following attributes are required: maxElementsInMemory - Sets the maximum number of objects that will be created in memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. The following attributes are optional: timeToIdleSeconds - Sets the time to idle for an element before it expires. i.e. The maximum amount of time between accesses before an element expires Is only used if the element is not eternal. Optional attribute. A value of 0 means that an Element can idle for infinity. The default value is 0. timeToLiveSeconds - Sets the time to live for an element before it expires. i.e. The maximum time between creation time and when an element expires. Is only used if the element is not eternal. Optional attribute. A value of 0 means that and Element can live for infinity. The default value is 0. diskPersistent - Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value is 120 seconds. --> <defaultCache maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="120" timeToLiveSeconds="120" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> </ehcache> |
public Cache(String name, int maxElementsInMemory, boolean overflowToDisk, boolean eternal, long timeToLiveSeconds, long timeToIdleSeconds, boolean diskPersistent, long diskExpiryThreadIntervalSeconds) { ... } |
//Create
a CacheManager using defaults CacheManager manager = CacheManager.create(); //Create a Cache specifying its configuration. Cache testCache = new Cache("test", maxElements, true, false, 60, 30, false, 0); manager.addCache(cache); |
manager.addCache(testCache); |
CacheManager
manager = CacheManager.create(); |
CacheManager
manager = CacheManager.create("src/config/ehcache.xml"); |
URL
url = getClass().getResource("/anothername.xml"); CacheManager manager = CacheManager.create(url); |
InputStream fis = new FileInputStream(new
File("src/config/ehcache.xml").getAbsolutePath()); try { manager = CacheManager.create(fis); } finally { fis.close(); } |
manager.shutdown(); |
Cache
cache = manager.getCache("sampleCache1"); |
CacheManager
manager = CacheManager.create(); manager.addCache("test"); |
CacheManager
manager = CacheManager.create(); Cache cache = new Cache("test", 1, true, false, 5, 2); manager.addCache(cache); |
Element
element = new Element("key1", "value1" cache.put(new Element(element); |
Element
element = cache.get("key1"); |
<property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.Provider</property> |
<hibernate-mapping> <class name="com.somecompany.someproject.domain.Country" table="ut_Countries" dynamic-update="false" dynamic-insert="false" > ... </hibernate-mapping> |
<cache usage="read-write|nonstrict-read-write|read-only" /> |
<cache usage="read-write" /> |
/** * A Country Domain Object * * @hibernate.class table="COUNTRY" * @hibernate.cache usage="read-write" */ public class Country implements Serializable { ... } |
The @hibernate.cache usage tag should be set to one
of read-write, nonstrict-read-write and read-only.<cache
name="com.somecompany.someproject.domain.Country" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /> |
/** * Returns the advanced search facilities that should appear for this country. * @hibernate.set cascade="all" inverse="true" * @hibernate.collection-key column="COUNTRY_ID" * @hibernate.collection-one-to-many class="com.wotif.jaguar.domain.AdvancedSearchFacility" * @hibernate.cache usage="read-write" */ public Set getAdvancedSearchFacilities() { return advancedSearchFacilities; } |
<cache name="com.somecompany.someproject.domain.Country" maxElementsInMemory="50" eternal="false" timeToLiveSeconds="600" overflowToDisk="true" /> <cache name="com.somecompany.someproject.Country.advancedSearchFacilities" maxElementsInMemory="450" eternal="false" timeToLiveSeconds="600" overflowToDisk="true" /> |
<cache
name="net.sf.hibernate.cache.StandardQueryCache" maxElementsInMemory="5" eternal="false" timeToLiveSeconds="120" overflowToDisk="true"/> |
<cache
name="net.sf.hibernate.cache.UpdateTimestampsCache" maxElementsInMemory="5000" eternal="true" overflowToDisk="true"/> |
<cache name="query.AdministrativeAreasPerCountry" maxElementsInMemory="5" eternal="false" timeToLiveSeconds="86400" overflowToDisk="true"/> |
public List getStreetTypes(final Country country) throws
HibernateException { final Session session = createSession(); try { final Query query = session.createQuery( "select st.id, st.name" + " from StreetType st " + " where st.country.id = :countryId " + " order by st.sortOrder desc, st.name"); query.setLong("countryId", country.getId().longValue()); query.setCacheable(true); query.setCacheRegion("query.StreetTypes"); return query.list(); } finally { session.close(); } } |
query.setCacheable(true);
line caches the query.query.setCacheRegion("query.StreetTypes");
line sets
the name of the Query Cache.