Hibernate EhCache configuration tutorial
来源:互联网 发布:sql 毫秒转换成日期 编辑:程序博客网 时间:2024/05/16 13:02
Caching is facility provided by ORM frameworks which help users to get fast running web application, while help framework itself to reduce number of queries made to database in a single transaction. Hibernate also provide this caching functionality, in two layers.
- Fist level cache: This is enabled by default and works in session scope.
- Second level cache: This is apart from first level cache which is available to be used globally in session factory scope.
In this tutorial, I am giving an example using ehcache configuration as second level cache in hibernate.
How second level cache works
Lets write all the facts point by point:
- Whenever hibernate session try to load an entity, the very first place it look for cached copy of entity in first level cache (associated with particular hibernate session).
- If cached copy of entity is present in first level cache, it is returned as result of
load
method. - If there is no cached entity in first level cache, then second level cache is looked up for cached entity.
- If second level cache has cached entity, it is returned as result of
load
method. But, before returning the entity, it is stored in first level cache also so that next invocation to load method for entity will return the entity from first level cache itself, and there will not be need to go to second level cache again. - If entity is not found in first level cache and second level cache also, then database query is executed and entity is stored in both cache levels, before returning as response of
load()
method. - Second level cache validate itself for modified entities, if modification has been done through hibernate session APIs.
- If some user or process make changes directly in database, the there is no way that second level cache update itself until “
timeToLiveSeconds
” duration has passed for that cache region. In this case, it is good idea to invalidate whole cache and let hibernate build its cache once again. You can use below code snippet to invalidate whole hibernate second level cache.
About EhCache
Terracotta Ehcache is a popular open source Java cache that can be used as a Hibernate second level cache. It can be used as a standalone second level cache, or can be configured for clustering to provide a replicated coherent second level cache.
Hibernate ships with the ehcache library. If you want any particular version of ehcache, visit the Terracotta Ehcache download site:
http://www.terracotta.org/products/enterprise-ehcache
The maven dependency is for Ehcache 2.0 and any upgrades is:
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.0.0</version> <type>pom</type></dependency>
Configuring EhCache
To configure ehcache, you need to do two steps:
- configure Hibernate for second level caching
- specify the second level cache provider
Hibernate 3.3 and above
<property key="hibernate.cache.use_second_level_cache">true</property><property name="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</property>
Hibernate 3.2 and below
<property key="hibernate.cache.use_second_level_cache">true</property><property name="hibernate.cache.region.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>
Configuring entity objects
This may done in two ways.
1) If you are using hbm.xml
files then use below configuration:
<class name="com.application.entity.DepartmentEntity" table="..."> <cache usage="read-write"/></class>
2) Otherwise, if you are using annotations, use these annotations:
@Entity@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="department")public class DepartmentEntity implements Serializable { //code}
For both options, caching strategy can be of following types:
- none : No caching will happen.
- read-only : If your application needs to read, but not modify, instances of a persistent class, a read-only cache can be used.
- read-write : If the application needs to update data, a read-write cache might be appropriate.
- nonstrict-read-write : If the application only occasionally needs to update data (i.e. if it is extremely unlikely that two transactions would try to update the same item simultaneously), and strict transaction isolation is not required, a nonstrict-read-write cache might be appropriate.
- transactional : The transactional cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache can only be used in a JTA environment and you must specify
hibernate.transaction.manager_lookup_class
.
Query caching
You can also enable query caching. To do so configure it in your hbm.xml
:
<property key="hibernate.cache.use_query_cache">true</property>
and where queries are defined in your code, add the method call setCacheable(true)
to the queries that should be cached:
sessionFactory.getCurrentSession().createQuery("...").setCacheable(true).list();
By default, Ehcache will create separate cache regions for each entity that you configure for caching. You can change the defaults for these regions by adding the configuration to your ehcache.xml
. To provide this configuration file, use this property in hibernate configuration:
<property name="net.sf.ehcache.configurationResourceName">/ehcache.xml</property>
And use below configuration to override the default configuration:
<cache name="com.somecompany.someproject.domain.Country" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"/>
Please note that in ehcache.xml
, if eternal=”true”
then we should not write timeToIdealSeconds
, timeToLiveSeconds
, hibernate will take care about those values
So if you want to give values manually better use eternal=”false”
always, so that we can assign values into timeToIdealSeconds
, timeToLiveSeconds
manually.
timeToIdealSeconds=”seconds”
means, if the object in the global cache is ideal, means not using by any other class or object then it will be waited for some time we specified and deleted from the global cache if time is exceeds more than timeToIdealSeconds
value.
timeToLiveSeconds=”seconds”
means, the other Session or class using this object or not, i mean may be it is using by other sessions or may not, what ever the situation might be, once it competed the time specified timeToLiveSeconds
, then it will be removed from the global cache by hibernate.
Example application
In our example application, I have one DepartmentEntity
for which I want to enable second level cache using ehcache. Lets record the changes step by step:
1) hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatedemo</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create</property> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping class="hibernate.test.dto.DepartmentEntity"></mapping> </session-factory></hibernate-configuration>
2) DepartmentEntity.java
package hibernate.test.dto;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.UniqueConstraint;import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy;@Entity (name = "dept")@Table(name = "DEPARTMENT", uniqueConstraints = { @UniqueConstraint(columnNames = "ID"), @UniqueConstraint(columnNames = "NAME") })@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="department")public class DepartmentEntity implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID", unique = true, nullable = false) private Integer id; @Column(name = "NAME", unique = true, nullable = false, length = 100) private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
3) HibernateUtil.java
package hibernate.test;import java.io.File;import org.hibernate.SessionFactory;import org.hibernate.cfg.AnnotationConfiguration;public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new AnnotationConfiguration().configure(new File("hibernate.cgf.xml")).buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { // Close caches and connection pools getSessionFactory().close(); }}
4) TestHibernateEhcache.java
public class TestHibernateEhcache { public static void main(String[] args) { storeData(); try { //Open the hibernate session Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); //fetch the department entity from database first time DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //fetch the department entity again; Fetched from first level cache department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //Let's close the session session.getTransaction().commit(); session.close(); //Try to get department in new session Session anotherSession = HibernateUtil.getSessionFactory().openSession(); anotherSession.beginTransaction(); //Here entity is already in second level cache so no database query will be hit department = (DepartmentEntity) anotherSession.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); anotherSession.getTransaction().commit(); anotherSession.close(); } finally { System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1 System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 1 HibernateUtil.shutdown(); } } private static void storeData() { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); DepartmentEntity department = new DepartmentEntity(); department.setName("Human Resource"); session.save(department); session.getTransaction().commit(); }}
Output:
Hibernate: insert into DEPARTMENT (NAME) values (?)Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?Human ResourceHuman ResourceHuman Resource11
In above output, first time the department is fetched from database. but next two times it is fetched from cache. Last fetch is from second level cache.
- Hibernate EhCache configuration tutorial
- hibernate:net.sf.ehcache.config.Configurator#configure : No configuration found. Configuring ehcache from ehcache-failsafe.xml f
- hibernate ehcache
- hibernate ehcache
- hibernate ehcache
- hibernate ehcache
- hibernate ehcache
- hibernate ehcache
- Myeclipse+hibernate报错:No configuration found.关于(ehcache-failsafe.xml)
- Hibernate Tutorial
- Hibernate Tutorial
- Spring 4 and Hibernate 4 integration tutorial part 1 xml configuration
- hibernate Configuration
- hibernate + ehcache 二级缓存技术
- Hibernate中配置EHCache
- Hibernate+ehcache二级缓存技术
- Hibernate+ehcache二级缓存技术
- Hibernate+ehcache二级缓存技术
- linux基本指令操作-初级
- JDBC操作数据库
- javascript模拟实现Map
- 一个空格不可小视
- HDOJ 题目4489 The King’s Ups and Downs(组合DP打表)
- Hibernate EhCache configuration tutorial
- hdoj 2842 Chinese Rings 【递推 + 矩阵快速幂】
- Android手机的休眠状态
- 浅谈Java的==、equals()、hashcode()
- Hadoop(六)——子项目Pig
- 360校园招聘2016笔试题
- 配置vim编写C/C++程序时自动缩进
- POJ - 2236 Wireless Network(并查集)
- BOSH、长连接和短连接、http的理解