sbd2
sbd2

Reputation: 79

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;
}

Upvotes: 1

Views: 3091

Answers (3)

Kenny Wyland
Kenny Wyland

Reputation: 21870

Ran into this same problem and realized that it was caused by changing the name of one of my database fields and running the code without regenerating the ormlite_config.txt.

When the ORMLite system was trying to load my class config and initialize the DAOs, it saw the config in ormlite_config.txt said there was a fieldname called oldname and then looked at the java class definition and didn't see an instance variable for oldname so it threw an exception which corrupted the rest of the process.

So, if you run into this error, make sure you regenerate your ormlite_config.txt file and try running again.

Upvotes: 0

Med Mahdi Maarouf
Med Mahdi Maarouf

Reputation: 71

for everyone got this error,

WHY I GET THIS ERROR:

When beginning creating your DAO any runtime exception does interrupt your DAO initialization and it makes you got this error.

HOW TO SOLVE IT :

1 - Check every throw ORMlite and SQLite exception from your DaoHelper class.

2 - Try to correct every error you got and stop every exception that can be thrown.

3 - Run your application without any runtime exception when beginning creating your DAO.

Upvotes: 0

Mikhail Sidorov
Mikhail Sidorov

Reputation: 789

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;
}

Upvotes: 1

Related Questions