Wednesday, September 14, 2016

A generic method to get column-value map from Java JDBC ResultSet

The following method creates a column_name to value map from the Java JDBC ResultSet. It makes use of the meta data and Spring JdbcUtils class.

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;

public Map getColumnValueMapFromResultSet(ResultSet resultSet)
   throws SQLException {
  ResultSetMetaData metaData = resultSet.getMetaData();
  int columnCount = metaData.getColumnCount();
  Map columnValueMap = new LinkedCaseInsensitiveMap(columnCount );

  for (int i = 1; i <= columnCount; i++) {
   String columnName = JdbcUtils.lookupColumnName(metaData, i);
   Object value = JdbcUtils.getResultSetValue(resultSet, i);
   columnValueMap.put(columnName, value);
  }
  return columnValueMap;
 }

Monday, September 12, 2016

Java Annotation PostConstruct and Inheritance

It is quite confusing when the Java inheritance is mingled with the PostConstruct annotation. Based on my tests, I found the following. Suppose there are two classes.
  class A {
    @PostConStruct
    private void init(){
 
    }
  }

  class B extends A {

   }


Case 1

For the above case, the execution order is
  1. Constructor of A
  2. Constructor of B
  3. init method of A.
So the annotation @PostConstruct is inherited even when the annotated method is private in the parent class.

Case 2

Now if the class B has its own @PostConstruct method such as the following:
      @PostConstruct
      private void my_init(){
      }
   
Then the init() method of A will not be called. Instead, my_init() is called. So it seems that in the class hierarchy, only one PostConstruct annotated method is called.

Case 3

Now if the class B does not have its own @PostConstruct. But it overrides the @PostConstruct annotated method in its parent class.
  class A {
    @PostConStruct
    public void init(){
       System.out.println("A init()");
    }
  }

  class B extends A {
   @Override
   public void init(){
      System.out.println("B init()");
    }
   }
In this case the @PostConstruct method init() is called. But the init() method used is from class B. So it will print "B init()". Note that if the init() method in class A is private, then "A init()" will be printed out. In this case, the init() method of B is not an override method. Actually you have to remove its @Override annotation. Otherwise it won't compile.

Conclusion

In summary, if there is a method with the annotation @PostConstruct in a class C or its parent classes, then the annotated method will be called after the constructor of C is called. In case that @PostConstruct appears in multiple classes in the class hierarchy, the one closest to the class C will be called. Furthermore, if that annotated method is overridden by its subclasses, then the overriding method will be called. Of course, I think it is bad to declare the @PostConstruct annotated method as public or protected. It should be private so it won't be overridden.