Archive for the ‘Design Patterns’ category

Exploring Design Patterns in the JDK

November 8th, 2010

Design Patterns are software design solutions that can be applied in our daily software development to help us develop code that is flexible, resilient to change and easily understood (when you are familiar with the pattern). The JDK APIs employ patterns in several areas. So even if you aren’t familiar with patterns if you’ve programmed in Java, you’ve been developing against APIs that have been built using patterns.

» Read more: Exploring Design Patterns in the JDK

Developing a multithreaded test harness

March 5th, 2010

You can’t ignore the fact that web servers are multithreaded. We can hide as much as we want, but sooner or later you’ll find yourself in the situation where your application works fine during development and testing; but once it hits production you start hearing about “funny” things happening. While there are plenty of tools that can be used to simulate multiple users, they aren’t always the easiest to run locally and they seem to take to much time to modify while hot on the trail of a multithreading bug. Here I’ll discuss the approach I took when I was recently faced with this situation.
» Read more: Developing a multithreaded test harness

Taking Advantage of Spring MVC’s Default Behavior

February 11th, 2010

Over the last several months I have worked on several content heavy websites for one of our clients. When I say “content heavy”, I mean that 80%-90% of the pages in the application are static, or at least mostly static, a customer name, membership number, etc may need to be floated in, but not big data tables with dynamic data being pulled from the database. The marketing department manages this content with their content management system and publish fully formed HTML pages (layout, look and feel, etc is controlled in the CMS) which are then pulled into our /WEB-INF/jsp/content directory by our build process.

Our applications treat these HTML pages as JSPs (simple rename in the build script). This lets the marketing team work from a cheat sheet of EL expressions such as ${customerName} and keeps the IT department out of the day to day content management work. One of our goals with these systems was to easily and seamlessly deal with both static pages and very dynamic pages requiring custom controllers to be built. With just a little bit of work Spring MVC makes it easy to provide this functionality and also provides a sane set of defaults for building out these web sites one page at a time.
» Read more: Taking Advantage of Spring MVC’s Default Behavior

Building Multi-Criteria Search Queries in Hibernate

December 9th, 2009

In this post I am going to show how to write queries multi-criteria search screens. There are two approaches for making this possible.

  • HQL for building the Query
  • Building Query using Criteria API

HQL for building the Query

Here I am going to show 2 approaches to building the HQL and try to point out the better approach.

Approach I:String concatenation
This approach uses String concatenation and setting up the values directly in the query.

if (startDate != null) {
   if (firstClause) {
      query = query + " where ";
   }
   else {
      query = query + " and ";
   }
 
   query += " s.date >= '" + startDate + "'";
}

Using the above approach there might be a chance of SQL Injection attack and using string concatenation is inherently error-prone.

Approach 2: Criteria as Named Parameters

In this one we create two map to hold parameter name and value which could be binded to the HQL during the execution.

Here is brief example of the approach.

public List search() {
   StringBuilder aQuery = 
      new StringBuilder(" from document p where p.id is not null ");
   HashMap parameterMap = new HashMap();
   HashMap parameterListMap =  new HashMap();
 
   //Collection Criteria
   if (countyList != null) {
      buildCollectionCriterion(aQuery, parameterListMap, "listID", countyList);
   }
 
   //Date Criteria
   if (startDate!= null || endDate != null) {
      buildDateCriterion(aQuery, parameterMap, "dateField",startDate, endDate);
   }
 
   Query query = hibSession.createQuery(aQuery.toString());
 
   for (String key : parameterMap.keySet()) {
      query.setParameter(key, parameterMap.get(key));
   }
 
   for (String key : parameterListMap.keySet()) {
      query.setParameterList(key, parameterListMap.get(key));
   }
 
   List results = query.list();
}
 
//Helper Methods for different type of criteria
 
protected void buildCollectionCriterion(StringBuilder aQuery, 
                                        Map parameterListMap, 
                                        String aFieldName, 
                                        Collection aList) {
   if (aList != null && !aList.isEmpty()) {
      aQuery
         .append(" and p.")
         .append(aFieldName)
         .append(" in (:")
         .append(aFieldName)
         .append(")");
      parameterListMap.put(aFieldName, aList);
   }
}
 
public void buildDateCriterion(StringBuilder aQuery, 
                               Map parameterMap, 
                               String aFieldName, 
                               Date aStartDate, 
                               Date anEndDate) {
   if (aStartDate != null && anEndDate != null) {
      aQuery
         .append(" and ( p."
         .append(aFieldName)
         .append(" between :aStartDate and :anEndDate)");
      parameterMap.put("aStartDate", aStartDate);
      parameterMap.put("anEndDate", anEndDate);
   }
   else if (aStartDate != null) {
      aQuery
         .append(" and  (p.")
         .append(aFieldName)
         .append(" >= :aStartDate)");
      parameterMap.put("aStartDate", aStartDate);
   } 
   else if (anEndDate != null) {
      aQuery
         .append(" and (p.")
         .append(aFieldName)
         .append(" <=:anEndDate");
      parameterMap.put("anEndDate", anEndDate);
   }
}

Building Query using Criteria API

public List search() {
        Criteria c = hibSession.createCriteria(Document.class);
        c.add(Restrictions.notNull("id"));
 
        if(countryList != null) {
                c.add(Restrictions.in("listId", countryList));
        }
 
        if(startDate != null) {
                c.add(Restrictions.ge("dateField", startDate);
        }
 
        if(endDate != null) {
                c.add(Restrictions.le("dateField", endDate);
        }
 
        return c.list();
}

Conclusion

The Hibernate Criteria API is a powerful and elegant library which is well adapted for implementing multi-criteria search functionality and also HQL queries must be built ‘on-the-fly’. Using it in appropriate circumstances will result in cleaner, clearer, more reliable and more maintainable code.