web-dev-qa-db-ja.com

既に閉じられたデータベースを再び開く部屋の試み

Android Architecture ComponentsのRoomを使用しているときに、Daggerコンポーネントを使用してデータベースにアクセスしようとすると、次のエラーが表示されました。

Java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: (database path)

Daggerバージョン2.11およびRoomバージョン1.0.0-alpha7を使用していました。このエラーは、バージョン1.0.0-alpha5で再現可能でした。

データベースを初期化し、クラスに挿入した後、DAOを介してデータベースにアクセスしようとすると、このエラーが発生しました。

31
huw

これは、移行情報を提供せずに既存のデータベースのスキーマを変更しようとしているためです。したがって、基本的には、動作しない既存のDBに新しいデータベーススキーマを書き込もうとします。

これには2つの方法があります。開発環境にいる場合、破壊的な移行にフォールバックすることができます。これを行うには、データベース作成コードは次のようになります。

MyDatabase myDatabase = Room.databaseBuilder(context, MyDatabase.class, "my-db")
    .fallbackToDestructiveMigration()
    .build();

つまり、データベースに更新されたエンティティまたは新しいエンティティを提供すると、@ huwからの回答が実行され、アプリケーションのインストールでデータベースが削除され、そこからすべてのデータが削除され、新規インストールが行われます。

もう1つの方法は、移行機能を使用することです。彼らはかなり長いので、誰かが私にここにそれを書きたいと思わない限り、私は今のところそれを残しますが、基本的に、ドキュメントはここにあります:

Room DB移行ドキュメント

これにより、基本的に、データベースが新しいバージョンに更新するために、DBが自分で提供したSQLを実行します。これにより、移行中にデータが失われないようにすることができます。またはあなたが何をしているかに応じて可能な限り少ない。これは、ユーザーが既存のデータを失うことはなく、多くの怒りのレビューや顧客の損失を招くことがないため、本番アプリに適した方法です。

それが助けになることを願っています!

81
James Lendrem

この問題の解決策の1つは、データベースファイルを削除して再起動することでした。私はテストしているだけで、オンラインデータを使用してデータベースを再作成できるため、これは問題ではありませんでした。

これを行うには:

  • アプリ情報>ストレージ>データの消去
  • /data/data/com.app.example/databases/database.dbにあるファイルを手動で削除します
15
huw

移行がそれほどうまくいかなかった後、この種の例外が発生しました。移行に使用するSQLクエリを常に再確認してください。間違ったタイプのデータで新しい列を作成できますが、例外の説明は役に立ちません。

0
lomza