javasqlmap

java Object null after instance and calling inside method


can anyone help me with this issue, i'm working with java using SQLMap(ibatis). i have 3 class which is MainConfiguration, SQLMap, DBUtility.

  1. Main Configuration (this class is using to set an object inside SQLMap class)

public class MainConfiguration
{
     public static String file = "configuration/db/SQLMapConfig.conf";

     public static void main(String[] args) throws Exception
     {
        new MainConfiguration().loadConfiguration();    
     }  

     public static void loadConfiguration()
     {
        SQLMap.setMapFile(file);
        List list = DBUtility.loadUsers();
     }
}
  1. SQL Map (this class is the getter and setter of and object)

public final class SQLMap
{
    private static SqlMapClient sqlMap;

    public static void setMapFile(String sMapFile)
    {
        try
        {
            sqlMap = SqlMapClientBuilder.buildSqlMapClient(new FileReader(sMapFile));
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error initializing SqlMapClient class", e);
        }
    }

    public static SqlMapClient getSqlMapInstance()
    {
        return sqlMap;
    }
}
  1. DBUtility (this class is where object instance and get object from SQLMap class)

    public class DBUtility
    {
    // object utility
    protected static SqlMapClient sqlMap = SQLMap.getSqlMapInstance();
    
    //constructor
    public DBUtility() throws Exception
    {
    }
    
    public static List loadUsers()
    {
        //it's working
        logger.info("SQLMap Get Instance = " + SQLMap.getSqlMapInstance());
    
        //it's not working
        logger.info("SQLMap Get Instance = " + sqlMap);
    
        //code below will be error because of null sqlMap
        try
        {
            listUser = sqlMap.queryForList("getUsers");
        }
        catch (Exception sqle)
        {
            logger.error("Error on load all user", sqle);
        }
        return listUser;
    }
    }
    

the logger give me this :

SQLMap Get Instance = com.ibatis.sqlmap.engine.impl.SqlMapClientImpl@76707e36

SQLMap Get Instance = null

how come the second log give me null, even i have instance the object?


Solution

  • Your field sqlMap is initialized when the DBUtility class is loaded, which apparently happens before SQLMap.setMapFile(file); is called. So, sqlMap points at different things: null in the static field, and an actual instance when you call the getter in loadUsers().

    The problem is that DBUtility looks up the sqlMap too early. It has to wait until the file is passed to SQLMap. Change your code like this to delay the initialization of DbUtility.sqlMap:

    public static void loadConfiguration()
    {
        SQLMap.setMapFile(file);
        DBUtility.initMapClient();  // notify DBUtility
        List list = DBUtility.loadUsers();
    }
    
    public class DBUtility
    {
        protected static SqlMapClient sqlMap;  // do not initialize too early
    
        public static void initMapClient()
        {
            sqlMap = SQLMap.getSqlMapInstance();  // wait for SQLMap to be ready
        }
    

    Of course, it would be simpler if you did not even have the sqlMap field in DBUtility. Just call SQLMap.getSqlMapInstance() every time you need it. This is especially important in case the instance ever changes:

    listUser = SQLMap.getSqlMapInstance().queryForList("getUsers");
    

    Read When are static variables are initialized? for a more detailed explanation of static fields.