Search code examples
androiddaoormlite

OrmLite java.lang.IllegalStateException: you must call initialize() before you can use the dao


I am using ORMLite to persist my object in my SqliteDatabase in my app.

I am getting this exception while trying to get a DAO in order to persist an object.

The documentation says I have to call the initialize() method before I can use the DAO, and the OrmLite documentation (insufficient) says:

BaseDaoImpl (class)
initialize(): Initialize the various DAO configurations after the various setters have been called.

The problem is, I get the DAOs by calling getDao(class), and there is no initialize() that I can call neither on DAOs nor in my class that extends OrmLiteSqliteOpenHelper.

This is my custom OpenHelper class code:

public class LocalDBHelper extends OrmLiteSqliteOpenHelper {
  private LocalDBHelper(Context context){
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }

  public static LocalDBHelper getInstance(Context context) {
    if (instance == null) instance = new LocalDBHelper(context);
    return instance;
  }

  @Override
  public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
    try {
        TableUtils.createTable(connectionSource, Barrio.class);
        TableUtils.createTable(connectionSource, Fenomeno.class);
        TableUtils.createTable(connectionSource, Info.class);
        TableUtils.createTable(connectionSource, TelefonoUtil.class);
        TableUtils.createTable(connectionSource, Alarma.class);
        TableUtils.createTable(connectionSource, ReplicaAlerta.class);
    } catch (SQLException e) {
        e.printStackTrace();
        Log.d(TAG, e.getMessage());
    }
  }

  @Override
  public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int oldVersion, int newVersion) {
    try {
        TableUtils.dropTable(connectionSource, Barrio.class, true);
        TableUtils.dropTable(connectionSource, Fenomeno.class, true);
        TableUtils.dropTable(connectionSource, Info.class, true);
        TableUtils.dropTable(connectionSource, TelefonoUtil.class, true);
        TableUtils.dropTable(connectionSource, Alarma.class, true);
        TableUtils.dropTable(connectionSource, ReplicaAlerta.class, true);
    } catch (SQLException e) {
        e.printStackTrace();
        Log.d(TAG, e.getMessage());
    }
  }

And this is the full stack of Android Monitor:

java.lang.IllegalStateException: you must call initialize() before you can use the dao
        at com.j256.ormlite.dao.BaseDaoImpl.checkForInitialized(BaseDaoImpl.java:1061)
        at com.j256.ormlite.dao.BaseDaoImpl.create(BaseDaoImpl.java:316)
        at com.org.siam.app.controller.BarrioController.actualizarTodos(BarrioController.java:75)
        at com.org.siam.app.remote.BarriosWebService.onResponse(BarriosWebService.java:43)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

EDIT: added an Application subclass called SiacApplication, onCreate() method code here (also registered on manifest):

@Override
public void onCreate() {
    super.onCreate();
    LocalDBHelper.getInstance(this);
}

EDIT 2: added DAO getter (the DAO is a local field):

    public Dao<Barrio, Long> getBarrioDao() throws SQLException {
    if (barrioDao == null) barrioDao = getDao(Barrio.class);
    return barrioDao;
}

Solution

  • Faced the same problem in Android. It seems that it's required to send ConnectionSource while creating DAO.

    In my case only creating wrapper classes for DAO helped because there is no getDao() method variation with such parameter.

    So i created wrapper

    class BarrioDao {
      public BarrioDao(ConnectionSource connectionSource) throws SQLException{
            super(connectionSource, Barrio.class); 
     }
    }
    

    getter for dao in LocalDBHelper looked like:

    public BarrioDao getBarrioDao() throws SQLException {
        if (barrioDao == null) barrioDao = new BarrioDao(getConnectionSource());
        return barrioDao;
    }