【问题标题】:Room.createFromAsset() rewrite app's database every time the app is openedRoom.createFromAsset() 每次打开应用程序时都会重写应用程序的数据库
【发布时间】:2020-04-26 14:58:35
【问题描述】:

堆栈溢出

我正在尝试在首次安装时从资产数据库初始化我的应用程序的数据库。但是,它可以正常工作,直到应用程序关闭。当我再次打开应用程序时,它会调用 createFromAsset()。据我所知,问题在于我正在获取应用程序数据库的一个实例并用资产数据库重写它。 只有在第一次安装应用程序时,我才不会调用 createFromAsset()。

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

以防万一有实体和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);
}

【问题讨论】:

标签: java android orm android-room android-room-prepackageddatabase


【解决方案1】:

删除fallbackToDestructiveMigration()。没必要这么叫。

INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            ActivityPackageDatabase.class, "appDB")
                            .createFromAsset("database/assetDB.db")
                            .build();

【讨论】:

  • 谢谢,现在可以使用了。有趣的是为什么房间认为迁移正在发生。
  • @Zaharlan,如果您更新数据库版本会发生什么?数据库是从更新后的应用程序附带的新资产文件中重新创建的,还是会尝试迁移并在未提供迁移的情况下失败,因为 fallbackToDestructiveMigration 指示不存在。
最近更新 更多