Praveen Singh

Introducing EhCache

Introduction


Introducing EhCache

There is a magic trick, which can turn a website from slow to fast, from fast to even faster !

That magic trick is cache !

Going back to my old days, i can recall the cache in my first project.It was nothing but a LRU map, provided by apache foundation.Working of that 'old-school' cache was pretty simple.Get the request.Identified the unique pattern i.e. key.Search in the map.if you get the object related to key, return the response.Else, create the response, update the cache, then return the respone.

Now, at this stage,you might be thinking, what else we need from a cache system ?

Lets see, what else we can expect !

  • Flexibility to use both memory and disk for cache.
  • Flexibility to set the size of both.
  • Not only in no of nodes, but in terms of MB also
  • Expiration time for data (object).
  • Flexibility on policy, LRU, FIFO, etc
  • Persistent of cache on disk, in case of server restart or application update.
  • Reporting : for cache miss and cache hit.
These are few to mention !

In my first video, i am going to explain when, where and why to use cache.

When, where and why to use cache.

step by step video tutorial







when, where and why to use cache.\ I am going to build a small application, where we are using ehcache for to build to whole cache system. I am first putting the video, then all code are provided afterwards. Code are provided in order they appear in video.
(if you find difficulty in following things, just drop your comment on this blog)

ehcache.xml

<ehcache>
<defaultcache eternal="false" maxelementsinmemory="10000" memorystoreevictionpolicy="LRU" overflowtodisk="false" statistics="true" timetoidleseconds="120" timetoliveseconds="120">

<cache eternal="false" maxelementsinmemory="1" memorystoreevictionpolicy="LRU" name="newsCache" overflowtodisk="false" statistics="true" timetoidleseconds="300" timetoliveseconds="600">

</cache></defaultcache></ehcache>


EHCacheManger.java
 package com.newslive.actions.cache.EChache
 import java.net.URL;

 import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheManager;

 public class EHCacheManger {

 	private static Cache newsCache;

 	private static EHCacheManger manager = new EHCacheManger();

 	private EHCacheManger() {
 		URL url = getClass().getResource("/config/ehcache.xml");
 		CacheManager manager = new CacheManager(url);
 		EHCacheManger.newsCache = manager.getCache("newsCache");
 	}

 	public static Cache getCache() {
 		return EHCacheManger.newsCache;
 	}

 }
EHCacheManger.java

 package com.newslive.actions.cache.EChache;

 import java.net.URL;

 import net.sf.ehcache.Cache;
 import net.sf.ehcache.CacheManager;

 public class EHCacheManger {

 	private static Cache newsCache;

 	private static EHCacheManger manager = new EHCacheManger();

 	private EHCacheManger() {
 		URL url = getClass().getResource("/config/ehcache.xml");
 		CacheManager manager = new CacheManager(url);
 		EHCacheManger.newsCache = manager.getCache("newsCache");
 	}

 	public static Cache getCache() {
 		return EHCacheManger.newsCache;
 	}

 }

AddNews.java
 package com.newslive.controller;

 import java.io.IOException;
 import java.io.PrintWriter;

 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 import com.newslive.actions.db.entity.News;
 import com.newslive.actions.services.NewsServicesEhCache;


 public class AddNews extends HttpServlet {
 	private static final long serialVersionUID = 1L;

 	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 		News news = new News();
 		news.setNewsHeading(request.getParameter("newsHeading"));
 		news.setNewsBody(request.getParameter("newsBody"));

 		NewsServicesEhCache service = new NewsServicesEhCache();
 		PrintWriter pw = response.getWriter();
 		try {
 			service.addNews(news);
 			pw.print("News added sucessfully");
 		} catch (Exception e) {
 			pw.print("oops ! - " + e.getMessage());
 			e.printStackTrace();
 		} finally {
 			pw.flush();
 			pw.close();
 		}
 	}
 }


NewsServicesEhCache.java
 package com.newslive.actions.services;

 import java.util.List;

 import net.sf.ehcache.Cache;
 import net.sf.ehcache.Element;

 import com.newslive.actions.cache.EChache.EHCacheManger;
 import com.newslive.actions.db.dao.NewsDAO;
 import com.newslive.actions.db.entity.News;

 public class NewsServicesEhCache {

 	public void addNews(News news) throws Exception {
 		NewsDAO newsDao = new NewsDAO();
 		int insertCount = newsDao.addNews(news);

 		Cache cache = EHCacheManger.getCache();
 		cache.put(new Element(new Integer(insertCount), news));

 	}

 	public List < news > getHeadlineList() throws Exception {
 		NewsDAO newsDao = new NewsDAO();
 		return newsDao.getHeadLineList();
 	}

 	public News getNews(int newsId) throws Exception {
 		News news = null;
 		Cache cache = EHCacheManger.getCache();
 		Element element = cache.get(new Integer(newsId));
 		if (element == null) {
 			System.out.println("cache miss");
 			NewsDAO newsDao = new NewsDAO();
 			news = newsDao.getNews(newsId);
 			cache.put(new Element(new Integer(newsId), news));
 		} else {
 			System.out.println("cache hit");
 			news = (News) element.getObjectValue();
 		}

 		return news;
 	}

 }


NewsDAO.java
    
 package com.newslive.actions.db.dao;

 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;

 import com.newslive.actions.db.entity.News;

 public class NewsDAO extends BaseDao {

 	public int addNews(News news) throws Exception {
 		Connection con = null;
 		PreparedStatement stmt = null;
 		int insertCount = -1;
 		con = super.getJDDBCConn();
 		stmt = con.prepareStatement("insert into news (newsHeading,newsBody) values (?,?)");
 		stmt.setString(1, news.getNewsHeading());
 		stmt.setString(2, news.getNewsBody());
 		stmt.executeUpdate();

 		Statement select = con.createStatement();
 		ResultSet result = select.executeQuery("SELECT max(id) FROM news");
 		while (result.next()) {
 			insertCount = result.getInt(1);
 		}
 		closrStmtConn(stmt, con);
 		return insertCount;
 	}

 	public List < news > getHeadLineList() throws Exception {
 		Connection con = null;
 		PreparedStatement stmt = null;
 		con = super.getJDDBCConn();
 		Statement select = con.createStatement();
 		ResultSet result = select.executeQuery("SELECT id, newsHeading FROM news");
 		List < news > newsList = new ArrayList < news > ();

 		while (result.next()) {
 			News news = new News();
 			news.setId(result.getLong(1));
 			news.setNewsHeading(result.getString(2));
 			newsList.add(news);
 		}
 		closrStmtConn(stmt, con);
 		return newsList;
 	}

 	public News getNews(int newsId) throws Exception {
 		Connection con = null;
 		PreparedStatement stmt = null;
 		con = super.getJDDBCConn();
 		stmt = con.prepareStatement("Select newsHeading, newsBody FROM news where id = ?");
 		stmt.setInt(1, newsId);
 		ResultSet result = stmt.executeQuery();
 		News news = new News();
 		if (result.next()) {
 			news.setNewsHeading(result.getString(1));
 			news.setNewsBody(result.getString(2));
 		}
 		closrStmtConn(stmt, con);
 		return news;
 	}
 }
DisplayHeadline.java
    
	package com.newslive.controller;

	import java.io.IOException;
	import java.util.List;

	import javax.servlet.ServletException;
	import javax.servlet.http.HttpServlet;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletResponse;

	import com.newslive.actions.db.entity.News;
	import com.newslive.actions.services.NewsServicesEhCache;

	/**
	 * Servlet implementation class DisplayHeadline
	 */
	public class DisplayHeadline extends HttpServlet {
		private static final long serialVersionUID = 1L;

		protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

			NewsServicesEhCache services = new NewsServicesEhCache();
			try {
				List < news > headLines = services.getHeadlineList();


				request.setAttribute("headLines", headLines);
				request.getRequestDispatcher("DisplayHeadline.jsp").forward(request, response);


			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}
	
DisplayNews.java
 package com.newslive.controller;

 import java.io.IOException;

 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 import com.newslive.actions.db.entity.News;
 import com.newslive.actions.services.NewsServicesEhCache;

 /**
  * Servlet implementation class DisplayNews
  */
 public class DisplayNews extends HttpServlet {
 	private static final long serialVersionUID = 1L;

 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 		String newsId = request.getParameter("newsId");
 		NewsServicesEhCache service = new NewsServicesEhCache();
 		try {
 			News news = service.getNews(Integer.parseInt(newsId));
 			request.setAttribute("news", news);
 			request.getRequestDispatcher("DisplayNews.jsp").forward(request, response);

 		} catch (NumberFormatException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		} catch (Exception e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
 	}



 }

Statastics.java


 package com.newslive.controller;

 import java.io.IOException;
 import java.io.PrintWriter;

 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 import com.newslive.actions.cache.EChache.EHCacheManger;

 import net.sf.ehcache.Cache;
 import net.sf.ehcache.Statistics;

 /**
  * Servlet implementation class Statastics
  */
 public class Statastics extends HttpServlet {
 	private static final long serialVersionUID = 1L;


 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 		Cache cache = EHCacheManger.getCache();
 		Statistics statistics = cache.getStatistics();
 		statistics.getCacheHits();
 		PrintWriter pw = response.getWriter();
 		pw.print("

NewsLive.com Statistics

"); pw.println("Cache name : " + statistics.getAssociatedCacheName()); pw.println(" Cache count : " + statistics.getMemoryStoreObjectCount()); pw.println(" Aveerage Time : " + statistics.getAverageGetTime()); pw.println(" Hits : " + statistics.getCacheHits()); pw.println(" Miss : " + statistics.getCacheMisses()); pw.flush(); pw.close(); } }
Menu.html


    <title>NewsLive.com</title>
<h2 style="color: maroon; margin-left: 200px;">NewsLive.com</h2><a href="http://www.blogger.com/AddNews.html">Add News</a>
<a href="http://www.blogger.com/DisplayHeadline">Read News</a>
<a href="http://www.blogger.com/Statastics">See Statastics</a>
AddNews.html
    	

    	<title>NewsLive.com</title>
<h2 style="color: maroon; margin-left: 200px;">NewsLive.com</h2><form action="AddNews" method="POST">News Heading :  <input name="newsHeading" style="width: 400px;" type="text" />
News Body :      <textarea cols="50" name="newsBody" rows="10"></textarea>
<input style="margin-left: 200px;" type="submit" value="Submit" />
</form>
    
DisplayHeadline.jsp

    <%@page import="com.newslive.actions.db.entity.News"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"     pageEncoding="ISO-8859-1"%>




Insert title here
<% List headLines = (List)request.getAttribute("headLines");
for (News news : headLines) {
out.print("

"); out.print(news.getNewsHeading()); out.print("

"); } %>
DisplayNews.jsp
<%@page import="com.newslive.actions.db.entity.News"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"     pageEncoding="ISO-8859-1"%>

Insert title here
<% News news = (News)request.getAttribute("news");  	out.print("

" + news.getNewsHeading()+ "

"); out.print(news.getNewsBody()); %>



After having this small demo, lets move some thing which more important and more meaningful.
Now days every other J2EE (JEE 5) application with significant use of database, prefers HIbernate as ORM framework.
Ehcache gel with Hibernate, so nicely that you might not come to know that you are using ehcahe in your application.

My next video explain, how you can integrate ehcache with Hibernate.


Code


  1. TestEHCache.zip
  2. TestEHCacheHibernate.zip


8 comments:

  1. Hi this post is really so useful for me.. As i didnt worked on eclipse and other IDE, i just have a few basic questions about getting into my first step. How to configure my application to use ehcahe..? whether i need to include some jar file inside my application..

    ReplyDelete
  2. yes you will rajaram....if you are not using any IDE, then try to link jars using ANT or Maven.....if you don't want to use these build tools, then you have to build war from yourself, use google to know the right process.

    ReplyDelete
  3. Thanks !! I was able to implement caching for my application by following your instructions. Thanks again for taking time and posting this.

    Murugan.

    ReplyDelete
  4. Hi Praveen,
    thanks for this useful article, I wonder if you can tell me where exactly the connection between the ehcache and the actual web application .

    in this Documentation I've seen two steps for integrating my web application with ehcache
    http://ehcache.org/documentation/recipes/pagecaching

    but, in your sample I didn't find the "filter" tag on your web.xml file. as it's mentioned in the documentation.

    I hope you got the point and make this fuzzy point clear for me.

    ReplyDelete
  5. Hi Praveen,

    I am new to the ehcache and would like to use your sample application to build a working example. What do I need to do in order to get this setup in my standalone environment? (Web server, Database, etc.)

    Thanks,

    Mark

    ReplyDelete
  6. really thanku man,today i learnt new thing :) thanQ

    ReplyDelete
  7. Awesome demo, Keep it up..
    Did you ever had a chance to use ehcache in camel route, if so can you share that.
    Thank You

    ReplyDelete
  8. We have a problem with ehcache. We need to clean it once in a while remotely for testing code. When we run application, we do not need to get responses from server.

    We cannot use ClearAll(), because it is restricted here for security reasons.

    Is there any way to clean one particular ehcache remotely without cleaning all ehcaches?
    Could you give us a sample code how to do it?

    Are there some other options? Maybe it can be done by ehcache configuration?

    ReplyDelete