Friday, March 29, 2013

Don't use 'Query.list()' when you really need 'Query.uniqueResult()' in Hibernate.

I was motivated to discuss a little about this topic, since I am seeing a usage of hibernate which is capable of making server issues in your application. What I am going to discuss here, is very simple, but some developers are tend to do it in wrong way. Sometime, they are doing this intentionally for safe side.

When we are using hibernate Query to fetch a single instance, Query.uniqueResult() is being used except special scenarios. To use Query.uniqueResult(), we must make sure that query will return a single object. But some programmers are still used to do it with Query.list() method which can pull your application out into very inconsistency situation and issues which are very hard to discover the reason for failure. 

Just have a look into the following example.

public Account getAccountByAccountIdAndType(Long accountId, AccountType accountType) throws FetchAccountException {
 
    Account account = null;
    Query query = getSession().getNamedQuery("getAccountByAccountId");
    query.setLong("accountId", accountId); 
    query.setString("accountType", AccountType.SAVING.toString());
    List<Account> list = query.list();
    if (null != list && list.size() > 0) {
         account = list.get(0);
    }
    return account;
}

The above function is responsible to get Account instance for a given account number and type. Let's assume there can not be two accounts with the same type having same account number. 

If you carefully see the above code, the developer has applied many safe factors to minimize the exceptions. Some are even ambiguous. The above method will be functioning well until there is one Account with same type and account number and you expects that too. And also, it will execute well when there are more than one Account with same type and account number, which results wrong output and we don't actually need. 

What will happen, if there are more than one accounts with same type and same account number?

That will be a total failure of your application and you will have to compensate if banking system will be on this kind of state. Let's see how the above method will behave in this kind of situation. The above method will hide this critical exception and keeps application flow functioning. The function will get a list which is having the accounts and will return the first Account instance. Ultimately, this will result wrong outputs in your application. 

The programmer has added a safe factor to keep application flow functioning even with more than one accounts with same type and number. This is unnecessary and a kind of cheat programming. The programmer can survive for some time, the company who is working for, will have to compensate for loses. This is very poor programming. Some programmers do this intentionally as a safe factor, some are doing this as a quick fix for a defect. But this is very very dangerous.

Further the programmer has checked the "list" for NULL which is ambiguous, because hibernate does not return NULL list, instead it always returns empty list.

And other shortage of above method is, it may return NULL as the output which is not a good programming practice. Instead, you can throw an exception.

The getAccountByAccountIdAndType() method must return an exception in state. If the programmer used Query.uniqueResult() for this purpose, it returns the following exception keeping every one enlighten. We can take immediate action to get rid of this killer situation.

org.hibernate.NonUniqueResultException: query did not return a unique result: 2

We can improve the above function as follows.

public Account getAccountByAccountIdAndType(Long accountId, AccountType accountType) {
 
    Query query = getSession().getNamedQuery("getAccountByAccountId");
    query.setLong("accountId", accountId); 
    query.setString("accountType", AccountType.SAVING.toString());
    Account account = (Account)Query.uniqueResult();
    
    if (account == null) {
         throw new RuntimeException("Unable to find Account for account number :" + accountId);
    }
    return account;
}

Now the above method will return the exception when there are more than one account with same type and number.

If you want to send more specific error message rather than a hibernate exception message when you are having more than one account with same account number and type, you can put a try-catch block as follows.

public Account getAccountByAccountIdAndType(Long accountId, AccountType accountType) {
     
    Account account = null;
    try {
        Query query = getSession().getNamedQuery("getAccountByAccountId");
        query.setLong("accountId", accountId); 
        query.setString("accountType", AccountType.SAVING.toString());
        Account account = (Account)Query.uniqueResult();
    } catch(NonUniqueResultException) {
        throw new RuntimeException("Two account found with same account number and type : Acc No-" + accountId);
    }
    if (account == null) {
         throw new RuntimeException("Unable to find Account for account number :" + accountId);
    }
    return account;
}

As a conclusion, always use Query.uniqueResult() when you want to fetch a single object with hibernate Query and you should make sure your query will return a single object too.

Wednesday, March 20, 2013

How to set browser time to DateTimeItem in smart GWT?

The "DateTimeItem" item in Smart GWT allows you to specify the date and the time together as a single field and ultimately it can be mapped to java.util.Date field in your model (or a field in your controller class).

DateTimeItem startDateTime = new DateTimeItem("startDateTime","Start Datetime");

After picking a date from the calendar, the 'DateTimeItem' shows the value in the following format by default.

MM/dd/yyyy HH:mm

It sets the time part to 00:00. I wanted to have time part to set the browser's time.

After searching on the internet and doing some experiments, I ended up with the following solution.

I am creating a custom class by extending "DateTimeItem" class of smart GWT and overrides the 'transformInput' method.

package mypackage;

import java.util.Date;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.TimeZone;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.FormItemInputTransformer;
import com.smartgwt.client.widgets.form.fields.DateTimeItem;
import com.smartgwt.client.widgets.form.fields.FormItem;

public class MyDateTimeItem extends DateTimeItem {
 
     public MyDateTimeItem(String name, String title) {
        super(name, title);
        this.setUseTextField(true);
        this.setWidth(125);
        this.setInputTransformer(new FormItemInputTransformer() {
            @Override
            public Object transformInput(DynamicForm form, FormItem item, Object value, Object oldValue) {
               DateTimeFormat dtFormet    = DateTimeFormat.getFormat("MM/dd/yyyy HH:mm"); 
               String strCurrentDateTime  = dtFormet.format(new Date());
               String strSelectedDateTime = dtFormet.format((Date)value, TimeZone.createTimeZone(0));
    
               if (oldValue != null) { // Changing date.

                   if (strSelectedDateTime.split(" ")[1].equals("00:00")) { 
                        //Selecting new date time from the picker while keeping old value in the input field.
                        return strSelectedDateTime.split(" ")[0] + " " + strCurrentDateTime.split(" ")[1];
                   } 
                   return strSelectedDateTime;
               } 
     
               return strSelectedDateTime.split(" ")[0] + " " + strCurrentDateTime.split(" ")[1];   
           }
      });
   }
}
You can use the new component in the similar way in which the 'DateTimeItem' was used.

MyDateTimeItem startDateTime = new MyDateTimeItem("startDateTime","Start Datetime");

Monday, December 17, 2012

Spring Controller class for jQuery grid

I have already posted an article of creating jQuery grid using struts 2 action class. This post explains, how to write spring controller class which supports to implement a jQuery grid. If you want to get through of crating a jQuery grid with spring controller class, you must first read my previous post which has shown bellow.

How to use jQuery grid with struts 2 without plugin ?

I am not going to repeat the same stuff which I have explained in my previous post here, because this post has only a few slight differences from my previous post. The previous post used a struts 2 action class as controller and this post uses a spring controller class instead of that. And also, previous post uses Province model class directly to represent the data. In this post, I am using a ProvinceDTO (Data Transfer Object) to bring data into controller level. Except above, the whole technique of implementing grid is exactly similar to previous post. So I am 100% sure that, if you go through the previous post first, you will definitely implement the same grid with spring controller class.

When creating jQuery grid with JSON response data, we need to properly synchronize some fields with client side to work grid properly. Those fields include,

  • rows       -The number of rows for one page.
  • page       -The page number requested.
  • sord        -Sorting order.
  • sidx         -Sorting index.
  • total        -Total number of records.
  • records   -The number of records returned for particular search criteria.
  • _search   -Either 'true' or 'false' indicating a particular request is search or not.
  • oper        -The type of operation, either 'add', 'del' or 'edit'

There are a few more fields like above which I have not mentioned here. You can refer jQuery documentation to know those. 

In my previous post, with struts 2 action class, I have placed these fields with in the action class itself. With spring controller class, I created separate generic Data Transfer Object to keep these properties and also 'gridModel' which is a collection of any type holding grid data. Every Data Transfer Object which carries data to create jQuery grid must be inherited from this grid support Data Transfer Object. 

The code for grid support Data Transfer Object is as follows.

 package com.blimp.dto;

 import java.util.List;

 public class GridSupportDTO<T> { 

 private List<T> gridModel = null;
 
 private Integer rows = 0;
 private Integer page = 0;
 private String sord;
 private String sidx;
 private Integer total = 0;
 private Integer records = 0;
 private Boolean _search;
 private String oper = null;
 
 public List<T> getGridModel() {
      return gridModel;
 }
 public void setGridModel(List<T> gridModel) {
      this.gridModel = gridModel;
 }
 public Integer getRows() {
      return rows;
 }
 public void setRows(Integer rows) {
      this.rows = rows;
 }
 public Integer getPage() {
      return page;
 }
 public void setPage(Integer page) {
      this.page = page;
 }
 public String getSord() {
      return sord;
 }
 public void setSord(String sord) {
  this.sord = sord;
 }
 public String getSidx() {
      return sidx;
 }
 public void setSidx(String sidx) {
      this.sidx = sidx;
 }
 public Integer getTotal() {
      return total;
 }
 public void setTotal(Integer total) {
      this.total = total;
 }
 public Integer getRecords() {
      return records;
 }
 public void setRecords(Integer records) {
      this.records = records;
 }
 public Boolean get_search() {
      return _search;
 }
 public void set_search(Boolean _search) {
      this._search = _search;
 }
 public String getOper() {
      return oper;
 }
 public void setOper(String oper) {
      this.oper = oper;
 } 
}

In above class, 'gridModel' is a generic collection which carries data for the grid. Let's see my ProvinceDTO.java class which represent data for each a single grid row. 

 package com.blimp.dto;

 import java.io.Serializable;

 public class ProvinceDTO extends GridSupportDTO<ProvinceDTO> implements Serializable {

 private static final long serialVersionUID = 8805507589278247940L;
 
 private Long id;
 
 private String name;
 
 private String provinceStatus;

 public Long getId() {
      return id;
 }

 public void setId(Long id) {
      this.id = id;
 }

 public String getName() {
      return name;
 }

 public void setName(String name) {
      this.name = name;
 }

 public String getProvinceStatus() {
      return provinceStatus;
 }

 public void setProvinceStatus(String provinceStatus) {
      this.provinceStatus = provinceStatus;
 }
}

I am going to implement the same grid with same fields as my previous post. In my previous post, I have used Provice.java entity class, but here, I am using ProvinceDTO.java class, since I don't want to clutter my entity classes with grid specific attributes or don't want to extends from a class which has grid specific attributes. Other thing is, I am using Data Transfer Object pattern with this project.

Next, we'll see our spring controller class which supports to implement jQuery grid.

package com.blimp.webapp.controller;

import java.security.Principal;
import java.util.List;
import java.util.Locale;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.blimp.dto.Page;
import com.blimp.dto.ProvinceDTO;
import com.blimp.model.Province;

@Controller
public class ProvinceController {

    @Autowired
    private ProvinceService provinceService;
 
    @RequestMapping(value = "*search*", method = RequestMethod.GET)
    public @ResponseBody
    ProvinceDTO searchProvince(Principal principal, ProvinceDTO provinceDTO, 
    Model model, Locale locale) {
  
    try {
   
         Page<Province, ProvinceDTO> requestedPage = new Page<Province, ProvinceDTO>(); 
         requestedPage.setPage(provinceDTO.getPage());
         requestedPage.setRows(10);
   
         Page<Province, ProvinceDTO> resultPage = provinceService.findByCriteria(provinceDTO, requestedPage);
         List<ProvinceDTO> provinceList = resultPage.getResultDtoList();
   
         provinceDTO.setGridModel(provinceList);
         provinceDTO.setRecords(resultPage.getRecords());
         provinceDTO.setTotal(resultPage.getTotals());
   
    } catch (Exception e) {
         e.printStackTrace();
    }
  
    return ProvinceDTO;
  }
}

Note that, I have passed 'provinceDTO' as a parameter for above controller method and also the method returns the same 'provinceDTO' and ultimately as a JSON response to the browser. I have annotated the method with '@ResponseBody' annotation which converts what ever the returning stuff from this method into JSON. I have updated 'gridModel', 'records' and 'totals' with appropriate data. The methods of service layer, DAO layer are exactly similar as in my previous post. Don't be lazy, have a look on my previous post, If you really need to implement jQuery grid with spring controller class. 

From the client side Javascript code, you need only to change the 'url' and 'editurl' attributes of the grid as follows.

url:CONTEXT_ROOT + '/search'
editurl:CONTEXT_ROOT + '/edit'

I haven't implement the controller method for edit function in above controller class. That's it for this post. I hope this will be a good start working with jQuery grid and spring controller. If you have problem of achieving this, feel free to contact me with a simple mail. 

Sunday, November 18, 2012

How to read a dynamically growing file with Java?

This small post explains, how to read a text file which grows dynamically, using Java. The catalina.out file which displays tomcat's console is a good example for a file which grows dynamically. 

The following example shows, how to read tomcat's catalina.out file with Java. This file grows when the applications deployed on tomcat are being accessed by users. The following program displays newly adding contents of catalina.out file just one second delay and keep continuing it. 

The Java's 'RandomAccessFile' class provides great facilities to read this kind of files.  The major usage of it for the following program is, it provides a feature so that we can read a file from a particular point to onwards. Let's see our small program. 

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Timer;
import java.util.TimerTask;


public class ConsoleReader {

   /**
    * @param args
    */
    public static void main(String[] args) {
    File file = new File("/home/semika/apache-tomcat-7.0.25/logs/catalina.out");
       try {
           RandomAccessFile r = new RandomAccessFile(file, "r");
           //First time read
           String str = null;
           while((str = r.readLine()) != null) {
            System.out.println(str);
           }
           r.seek(r.getFilePointer());
           startTimer(r);
       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       } 
    }
 
    private static void startTimer(final RandomAccessFile r) {
     Timer timer = new Timer();
     timer.scheduleAtFixedRate(new TimerTask() {
     @Override
     public void run() {
     String str = null;
     try {
          while((str = r.readLine()) != null) {
           System.out.println(str);
          } 
          r.seek(r.getFilePointer()); 
     } catch (IOException e) { 
         e.printStackTrace();
     }
      }
 }, 0, 1000);
    }
}

In the above program, it reads catalina.out file line by line and displays it in console. When you run the program, it will read the whole file up to the end at first and then immediately start a timer to read dynamically adding contents to the file. The timer will always start to read file from a particular point, in above case, it will always start to read the file from the next line which last line was displayed.

While you are accessing your applications deployed in your tomcat container, just keep looking at the output of above program. You can see the tomcat's console just like, you have used to see it before.

Monday, November 12, 2012

Java enums are more than constant fields.

An enum is a type which defines set of fixed constants. For example, if you think generally, the seasons of the year, the planets in the solar system can be defined as enums. Also, you can identify constant types  in your application and defined those as enums which gives you much reliability, maintainability and also the flexibility. Enums were introduced to the Java language with 1.5 release which provides great functionality than what we know, and what we are using. Before introducing enums to the language, we used int, string constants which have many shortages. 

With this post, I am going to discuss the advantages of using enums and the shortcomings of using traditional constants approach. Suppose, we want to keep constant types for seasons of the year. Before enum was introduced, we normally defined a constant group as follows. 

 public static final int SEASON_SPRING = 3;
 public static final int SEASON_SUMMER = 6;
 public static final int SEASON_AUTUMN = 9;
 public static final int SEASON_WINTER = 12;
The value assigned for each field is, the starting month of the season. For example, the summer season will start from 6th month of the year. In real world, the starting month of each season will vary from country to country. I used above values just for illustration purpose. 

Let's discuss the shortcomings of the above approach when comparing with enum types. 

Constant fields don't provide type safety. Suppose you have written a method which returns the months belong to each season.

private List<String> getMonthsOfSeason(int seasonStartingMonth) {
  
    switch(seasonStartingMonth) {
       case 3:
           return CalendarUtil.getMonthsOfYear(new int[]{2,3,4});
           //[March, April, May]
       case 6:
           return CalendarUtil.getMonthsOfYear(new int[]{5,6,7});
           //[June, July, August]
       case 9:
           return CalendarUtil.getMonthsOfYear(new int[]{8,9,10});
           //[September, October, November]
       case 12:
           return CalendarUtil.getMonthsOfYear(new int[]{11,0,1});
           //[December, January, February]
       default:
           return new ArrayList<String>(); 
    }
}

If we use traditional int constants approach, we have to implement similar method like above to get the months of a season. I will show you the code for CalendarUtil class later in this post.

The above method accepts any integer value as the season starting month. By mistakenly, you may pass a different integer constant field (some number except 3,6,9,12) into the method instead of passing one of the season number which has been defined as constants above. In that kind of scenario, the method will returns empty list which may result unexpected output.

Though, You can add considerable validation to the above method, still that method is brittle. The other thing is, you may compare the parameter value with any integer since defined constants are integer type.

   
   If(seasonStartingMonth == QUATER_THREE) {
     //some code
   }

In the above code 'QUATER_THREE' is some different integer constant field defined in the same class for different purpose. Our programmer has mistakenly compared 'seasonStartingMonth' variable with QUATER_THREE constant field. But this is valid comparison, no compile error, but it will give wrong output. Programmer actually intended to compare 'seasonStartingMonth' variable with one of the our defined season constant field. 

Java does not provide namespaces to distinguish each constant groups. We have to use prefixes when two int constant groups have identically named fields. I have used SEASON_ for season group for that purpose. 

The int constants are compile-time constants. The int enums are compiled into the clients that use them. If the int associated with an enum constant is changed, its clients must be recompiled. If they aren’t, they will still run, but their behaviour will be undefined. 

The int constants don't give good debugging information. The int constant fields do not give helpful information when you are debugging your code. If you print some int constant field, it will print just a number which does not make sense. There is no easy way to translate int constant fields into printable strings. 

There is no reliable way to iterate over all the constants defined in a particular constant group and also the size of the constant group. 

Above, I have highlighted some of the shortcoming when using traditional constant field approach.

I have small utility class as follows.

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;


public final class CalendarUtil {

    //Returns list of names of the months for a given array of month numbers.
    public static List<String> getMonthsOfYear(int[] months) {
         List<String> monthArray = new ArrayList<String>(3);
         Calendar cal = Calendar.getInstance();

         for (int i = 0; i < months.length; i++) {
             cal.set(Calendar.MONTH, months[i]);
             monthArray.add(cal.getDisplayName(Calendar.MONTH,
                    Calendar.LONG, Locale.ENGLISH));
         }
         return monthArray;
    }
}

In the above utility class, the 'getMonthsOfYear()' method returns list of month's name for a given array of month numbers of the year.

Now,let's try to do the same thing by using enum. The following code shows an enum definition for seasons of the year.

import java.util.ArrayList;
import java.util.List;

public enum Season {

   SEASON_SPRING(3), //[March, April, May]
   SEASON_SUMMER(6), //[June, July, August]
   SEASON_AUTUMN(9), //[December, January, February]
   SEASON_WINTER(12);//[September, October, November]
 
   private final int startingMonth;
 
   SEASON(int startingMonth) {
       this.startingMonth = startingMonth;
   }
 
   public List<String> getMonthsOfSeason() {

       switch(startingMonth) {
           case 3:
             return CalendarUtil.getMonthsOfYear(new int[]{2,3,4});
           case 6:
             return CalendarUtil.getMonthsOfYear(new int[]{5,6,7});
           case 9:
             return CalendarUtil.getMonthsOfYear(new int[]{8,9,10});
           case 12:
             return CalendarUtil.getMonthsOfYear(new int[]{11,0,1});
           default:
             return new ArrayList$lt;String>(); 
       }
    }
}

See how Java enums are smart? Java enums are classes that export one instance for each enumeration constant via a public static final field. This kind of enum declaration provides compile time safety. For example, consider the following method.

private List<String> getMonthsOfSeason(Season season) {

}

This method guaranteed that it won't accept any other types of values except Season. If we try to pass some other types, compiler will point it out as an error. 

Since Java enum has it's own namespace, identically named constants can coexist with out any problem. For example, We can use same enum constant field name with another enum declaration. 

We can easily convert enum constant fields to printable string using toString() method.

Java enum allows us to keep methods and fields associated with it. In the above example, I have declared one field and method with the enum. I have defined the method with the enum it self which returns months of the season. This is very reliable and convenience implementation. The likelihood of happening bugs in the application is comparatively less. If we want to get the months of winter seasion, we can do it as follows.

List<String> months = Season.SEASON_WINTER.getMonthsOfSeason();

In the above example, the defined method behaves similarly for every constant field. But, We can implement method which behaves differently for each constant field on the enum. I have discussed about field specific method implementation with another post. Please have a look on following URL.

http://skillshared.blogspot.com/2012/01/java-enum-constant-specific-method.html

We can associate data with each constant field of a enum. I have specified starting month number with each constant field of Season enum. We can associate data as many with the enum constant field with the declared fields with corresponding types of data and also the constructor parallel to those data. Enums are immutable, so all fields should be final.

Also, if you want to iterate over all the constant fields of the enum, you can do it as follows.

for (Season s : Season.values()) {
   System.out.println("Months of seasion : " + s.toString());
   System.out.println(s.getMonthsOfSeason());
}

I am going to conclude this article with nice example. Consider the eight planets of our solar system. There are tow constant attribute for each planet has, a mass and a radius, and from these two attributes you can compute its surface gravity. This in turn lets you compute the weight of an object on the planet’s surface, given the mass of the object. Here’s how this enum looks.The numbers in parentheses after each enum constant are parameters that are passed to its constructor. In this case, they are the planet’s mass and radius.
public enum Planet {
    MERCURY(3.302e+23,2.439e6),
    VENUS (4.869e+24,6.052e6),
    EARTH (5.975e+24,6.378e6),
    MARS(6.419e+23,3.393e6),
    JUPITER(1.899e+27,7.149e7),
    SATURN (5.685e+26,6.027e7),
    URANUS (8.683e+25,2.556e7),
    NEPTUNE(1.024e+26,2.477e7);

    private final double mass;
    private final double radius;
    private final double surfaceGravity;

    private static final double G = 6.67300E-11;

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
        surfaceGravity = G * mass / (radius * radius);
   }

   public double mass() {
         return mass;
   }

   public double radius() {
         return radius;
   }

   public double surfaceGravity() {
         return surfaceGravity;
   }

   public double surfaceWeight(double mass) {
        return mass * surfaceGravity;
   }
}
Share

Widgets