Friday, September 08, 2006

Calculating page request times for your web application

It has been 3 weeks since I started developing jobBoard, a web application for online recruitment/jobs database. Time now for some performance numbers!

How do you accurately measure the processing time it takes for each request on your web application? An example,

  • User clicks on a link on a page
  • Request goes through a couple of servlet filters, e.g acegi, sitemesh filters
  • The corresponding controllers/actions process the request, calls DAOs
  • DAOs/ORMs queries the native database system and returns results to controller
  • Controller gets results from DAOs and puts request attributes to JSP/Velocity etc. page template
  • Page served up by the web server.

There's a good article on servlet filters with an example just to do the above. However, I needed to present the process time on the requested web page but once the filter chain is executed, I can't put the execution time as a request attribute to be used by the page template. But here's a neat trick.

Put the 'before' time into the request attribute,

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

  long before = System.currentTimeMillis();
  request.setAttribute("before", before); // add here
  chain.doFilter(request, response); 
  long after = System.currentTimeMillis();

Then in my JSP page,

Request processed in <%= System.currentTimeMillis() - Long.valueOf(pageContext.getRequest().getAttribute("before").toString()) %> ms

The values are the same as when using the example TimeFilter as it is

Process Time.

Friday, September 01, 2006

Testing your Java Persistence API queries interactively

One of aspects of developing with ORMs is to test your JPA, EJB, Hibernate QL queries and get the results you wanted before hard coding it into your web application. For Hibernate, there's Hibernate tools but what about JPA? And within the Spring framework. Fortunately, the Spring framework provides a class (org.springframework.test.jpa.AbstractJpaTests;) to test your DAOs, which you can just adapt to make a sort of 'Query Tester'.

Here's what I did

public class JpaJobboardTests extends AbstractJpaTests {

  private JobDao jobDao;
  
  protected String[] getConfigLocations() {
    return new String[] {
      "applicationContext-jpa.xml"
    };
  }
        
    public void testQuery() {
        Query q = sharedEntityManager.createQuery(

                "SELECT DISTINCT j FROM Job j " +
                "JOIN j.industries i " +
                "JOIN j.employmentTypes e " +
                "JOIN j.qualification q " +
                "WHERE " +
                "q.id BETWEEN 2 AND 4" +
                " AND " +
                "i.id IN (4) " +
                " AND e.id IN (3)"

                );
        List jobs = q.getResultList();
        Iterator iterator = jobs.iterator();
        while (iterator.hasNext()) {
            Job job = (Job)iterator.next();
            System.out.println(job.getId() + " : " + job.getPosition());
            System.out.println(job.getIndustries());
            System.out.println(job.getEmploymentTypes());
            System.out.println(job.getQualification().getId());
        }
    }

    public void testGetAllJobs() {
        List jobs = this.jobDao.findAll();        
    }
    
    public JobDao getJobDao() {
        return jobDao;
    }
    
    public void setJobDao(JobDao jobDao) {
        this.jobDao = jobDao;
    }
    
}

Plug it into my favorite IDE, and run it. You can edit your queries and see the results interactively.

Sure, you could code a seperate application just to do this, with named queries stored in a seperate XML file, and changing the queries in the external file, and not the source codes and recompiling every time.