web-dev-qa-db-fra.com

Tentative de salle pour rouvrir une base de données déjà fermée

Lors de l'utilisation de Room à partir des composants d'architecture Android, j'ai reçu le message d'erreur suivant lorsque je tentais d'accéder à la base de données à l'aide d'un composant Dagger:

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

J'utilisais Dagger version 2.11 et Room version 1.0.0-alpha7. L'erreur était reproductible sur la version 1.0.0-alpha5.

Cette erreur s'est produite lors de toute tentative d'accès à la base de données via un DAO après l'initialisation de la base de données et son injection dans ma classe.

26
huw

C'est parce que vous essayez de modifier le schéma de la base de données existante sans lui fournir d'informations de migration. Donc, fondamentalement, il essaie d'écrire le nouveau schéma de base de données dans la base de données existante, ce qui ne fonctionne pas.

Il y a deux façons de contourner cela. Si vous êtes dans votre environnement de développement, vous pouvez utiliser une migration destructive. Pour ce faire, le code de création de votre base de données ressemblerait à ceci:

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

Cela signifie que lorsque vous fournissez à la base de données une entité mise à jour ou nouvelle, elle répond à la réponse de @huw et supprime simplement la base de données sur l'installation de l'application en supprimant toutes les données et en effectuant une nouvelle installation.

L'autre méthode consiste à utiliser une fonction de migration. Ils sont assez longs, donc à moins que quelqu'un veuille que je l'écrive ici, je le laisse pour le moment, mais la documentation peut être trouvée ici:

Documentation de migration de la base de données Room

Cela oblige essentiellement la base de données à exécuter du code SQL que vous avez fourni pour mettre à jour la base de données vers la nouvelle version. De cette façon, vous pouvez vous assurer qu'aucune de vos données n'est perdue pendant la migration. ou aussi peu que possible en fonction de ce que vous faites. Il s'agit de la méthode préférée des applications de production car cela signifie que les utilisateurs ne perdront pas leurs données préexistantes et que vous ne recevrez pas beaucoup de critiques en colère/de clients perdus.

J'espère que ça aide!

69
James Lendrem

Une solution à ce problème consistait à supprimer le fichier de base de données et à recommencer. Ce n'était pas un problème puisque je ne faisais que tester et pouvais repeupler la base de données en utilisant des données en ligne.

Pour le faire soit:

  • Informations sur l'application> Stockage> Effacer les données
  • Supprimez manuellement le fichier à /data/data/com.app.example/databases/database.db
14
huw

J'ai eu ce genre d'exception après la migration pas si réussie. Vérifiez toujours la requête SQL que vous utilisez pour une migration. Vous pouvez créer une nouvelle colonne avec un type de données incorrect et la description de l'exception ne vous sera pas utile.

0
lomza