with tutorial studio room multiple example android sqlite android-room

tutorial - unique room database android



La migraciĆ³n de la base de datos de la sala no maneja adecuadamente la migraciĆ³n de ALTER TABLE (5)

El mensaje de error es difícil de analizar, pero hay una diferencia:

TableInfo {name = ''user'', columnas = {name = Column {name = ''name'', type = ''TEXT'', notNull = false, primaryKeyPosition = 0}, age = Column {name = ''age'', type = ''INTEGER '', notNull = true , primaryKeyPosition = 0}, id = Column {name ='' id '', type ='' INTEGER '', notNull = true, primaryKeyPosition = 1}}, foreignKeys = []} Encontrado:

Encontró

TableInfo {name = ''user'', columnas = {name = Column {name = ''name'', type = ''TEXT'', notNull = false, primaryKeyPosition = 0}, id = Column {name = ''id'', type = ''INTEGER '', notNull = true, primaryKeyPosition = 1}, age = Column {name ='' age '', type ='' INTEGER '', notNull = false , primaryKeyPosition = 0}}, foreignKeys = []}

La edad es anulable pero la Sala esperaba que no fuera nula.

Cambia tu migración a:

database.execSQL("ALTER TABLE ''user'' ADD COLUMN ''age'' INTEGER NOT NULL");

Como esta explicación de excepción es MUY difícil de analizar, he creado un pequeño script que hace la diferencia por usted.

Ejemplo:

mig "java.lang.IllegalStateException: Migration failed. expected:TableInfo{name=''user'', columns={name=Column{name=''name'', type=''TEXT'', notNull=false, primaryKeyPosition=0}, age=Column{name=''age'', type=''INTEGER'', notNull=true, primaryKeyPosition=0}, id=Column{name=''id'', type=''INTEGER'', notNull=true, primaryKeyPosition=1}}, foreignKeys=[]} , found:TableInfo{name=''user'', columns={name=Column{name=''name'', type=''TEXT'', notNull=false, primaryKeyPosition=0}, id=Column{name=''id'', type=''INTEGER'', notNull=true, primaryKeyPosition=1}, age=Column{name=''age'', type=''INTEGER'', notNull=false, primaryKeyPosition=0}}, foreignKeys=[]}"

Resultado:

Java.lang.IllegalStateException

La migración no manejó correctamente al usuario (therealandroid.github.com.roomcore.java.User).

Esperado:

TableInfo {name = ''user'', columnas = {name = Column {name = ''name'', type = ''TEXT'', notNull = false, primaryKeyPosition = 0}, age = Column {name = ''age'', type = ''INTEGER '', notNull = true, primaryKeyPosition = 0}, id = Column {name ='' id '', type ='' INTEGER '', notNull = true, primaryKeyPosition = 1}}, foreignKeys = []} Encontrado:

Encontró

TableInfo {name = ''user'', columnas = {name = Column {name = ''name'', type = ''TEXT'', notNull = false, primaryKeyPosition = 0}, id = Column {name = ''id'', type = ''INTEGER '', notNull = true, primaryKeyPosition = 1}, age = Column {name ='' age '', type ='' INTEGER '', notNull = false, primaryKeyPosition = 0}}, foreignKeys = []}

Estoy intentando realizar una migración simple, tengo una clase llamada User y tengo dos columnas ID (primary key) y NAME TEXT y luego lleno la base de datos con datos de dos usuarios, luego agrego la AGE la columna en el objeto User y en la constante de Migración agrego una alter table para agregar esta nueva columna y, por último, reemplazo la versión de la base de datos 1 a 2

Aquí está el código

Clase de usuario

@Entity(tableName = "user") public class User { @PrimaryKey private int id; @ColumnInfo(name = "name") private String name; @ColumnInfo(name = "age") private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

Clase de base de datos

@Database(entities = {User.class}, version = 2) public abstract class RoomDatabaseImpl extends RoomDatabase { abstract UserDao userDao(); }

Codigo de migracion

public static Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE ''user'' ADD COLUMN ''age'' INTEGER"); } };

y se llama

Room.databaseBuilder(context, RoomDatabaseImpl.class, "Sample.db") .addMigrations(MIGRATION_1_2) .allowMainThreadQueries() .build();

Antes de cambiar el objeto agregando AGE y realizando la migración, agrego dos registros y funciona.

Después de realizar la migración, solo intenté agregar un nuevo usuario como se muestra a continuación:

User user = new User(); user.setName("JoooJ"); user.setId(3); user.setAge(18); List<User> userList = new ArrayList<>(); userList.add(user); App.database(this).userDao().insertAll(userList); // The crash happens here

Otras informaciones:

Android Studio 3 y yo no probamos en el real.

Dependencias:

compile "android.arch.persistence.room:runtime:1.0.0-alpha9-1" annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha9-1" compile "android.arch.persistence.room:rxjava2:1.0.0-alpha9-1" gradle 2.3.3

Alguien me puede ayudar, por favor, realmente no sé qué estoy haciendo mal o si es un error.


Enfrenté este problema hoy, acabo de cambiar los campos int a Integer en Entities . Como int no puede ser nulo pero los objetos Integer podrían ser nulos.


Ninguna de las respuestas es correcta en ninguno de los enlaces. Después de muchos experimentos, encontró un camino para ello. La consulta ALTER debe escribirse de la siguiente manera para que funcione:

database.execSQL("ALTER TABLE ''user'' ADD COLUMN ''age'' INTEGER NOT NULL DEFAULT 0")

Sin embargo, el valor DEFAULT del entero puede ser cualquier cosa.

Si desea agregar una columna de tipo Cadena, agregue de la siguiente manera:

database.execSQL("ALTER TABLE ''user'' ADD COLUMN ''address'' TEXT")

Esto funciona como un encanto.


Si no está obteniendo diferencias, puede simplemente marcar su campo de clase con la anotación @NonNull, o cambiar su sql con ALTER TABLE. Pero si obtiene diferencias de tipo de columna, como las esperadas: TYPE = TEXT, luego se encuentra TYPE = '''' (COLLATE NOCASE), o INTEGER esperado, se encontró INT, entonces la única solución es eliminar y volver a crear su tabla. Sqlite no permite cambiar los tipos de columna.

Use INTEGER en Sqlite en lugar de INT y marque su entidad Java con @ColumnInfo (collate = NOCASE) (si usa NOCASE en Sqlite).

Eche un vistazo al archivo json en app / schemas para obtener el sql para las consultas esperadas.

static final Migration MIGRATION_2_3= new Migration(2, 3) { @Override public void migrate(SupportSQLiteDatabase database) { database.execSQL("DROP TABLE IF EXISTS table_tmp"); database.execSQL("CREATE TABLE IF NOT EXISTS `table_tmp` ..."); database.execSQL("insert into table_tmp (`id`, `name` , ..."); database.execSQL("DROP INDEX IF EXISTS `index_table_name`"); database.execSQL("CREATE INDEX IF NOT EXISTS `index_table_name` ON `table_tmp` (`name`)"); database.execSQL("DROP TABLE IF EXISTS table"); database.execSQL("alter table table_tmp rename to table"); } };


Yo también escribí un pequeño script JS que puedes encontrar https://hrankit.github.io/RoomSQLiteDifferenceFinder/

El proceso es bastante simple.

  1. Ingrese el registro de error esperado en la columna Esperado que es la izquierda.

  2. Ingrese el registro de error Encontrado en la columna Encontrada que es la correcta.

  3. Presione Ir. botón. Los registros de errores se convierten a JSON.

  4. Presione el botón Comparar y Voila, usted tiene la diferencia que necesita.

Este complemento descubre la diferencia en los dos volcados esperados y encontrados del Android Studio Logcat.

Echa un vistazo a la imagen de comparación aquí