3

I am trying to initialize my app's database from an asset database when it first installed. However, it works fine until the app is closed. When I open the app again it calls createFromAsset(). As far as I know, the problem is in the fact that I'm getting an instance of the app DB and rewriting it with the asset DB. I need createFromAsset() to be called only when the app installed for the first time.

@Database(entities = {ActivitySession.class}, exportSchema = true, version = 1)
public abstract class ActivityPackageDatabase extends RoomDatabase {

private static ActivityPackageDatabase INSTANCE;


public static ActivityPackageDatabase getDatabase(final Context context) {
        if (INSTANCE == null) {
            synchronized (ActivityPackageDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            ActivityPackageDatabase.class, "appDB")
                            .createFromAsset("database/assetDB.db")
                            .fallbackToDestructiveMigration()
                            .build();
                }
            }
        }
        return INSTANCE;
    }

Just in case there are examples of entities and DAO

@Entity
public class SessionPhoto {
    @PrimaryKey(autoGenerate = true)
    public long id;

    public long sessionId;
    public String path;

    public SessionPhoto() {
    }

    public long getSessionId() {
        return sessionId;
    }

    public void setSessionId(long sessionId) {
        this.sessionId = sessionId;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }
}
@Dao
public abstract class ActivitySessionDao {
    @Update(onConflict = OnConflictStrategy.REPLACE, entity = ActivitySession.class)
    public abstract void updateSession(ActivitySession activitySession);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public abstract void addNewJournalEntry(ActivityJournal journalEntry);

    @Insert
    public abstract long insertSession(ActivitySession activitySession);

    @Query("SELECT * FROM activitySession")
    public abstract LiveData<List<ActivitySession>> getAllSessionsRecords();

    @Transaction
    @Query("SELECT * FROM activityPackage WHERE id = :id")
    public abstract LiveData<List<ActivityWithSessions>> getActivityWithSessionById(long id);

    public  void cancelSession(ActivitySession session){
        session.completedDateTime = new Date();
        session.status = ActivityPackageStatus.CANCELED;
        updateSession(session);
    }
    @Query("SELECT * FROM activitysession WHERE activityId = :acitivityId AND id = :id")
    public abstract ActivitySession findSessionByActivityId(long acitivityId, long id);
}
Zain
  • 37,492
  • 7
  • 60
  • 84
Zaharlan
  • 75
  • 7

1 Answers1

5

Remove fallbackToDestructiveMigration(). no need to call that.

INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            ActivityPackageDatabase.class, "appDB")
                            .createFromAsset("database/assetDB.db")
                            .build();
Reza
  • 845
  • 13
  • 18
  • Thanks, it works now. Interestingly why room thinks that migration is happening. – Zaharlan Apr 26 '20 at 21:44
  • @Zaharlan, what will happen if you update the version of your DB? Will the DB be recreated from the new asset file shipped with the updated app, or will it try to migrate and will fail in case migration is not provided as fallbackToDestructiveMigration indication is not present. – Sarthak_ssg5 Aug 05 '21 at 09:07