Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

[Bug] AutoMigration Failure: Please declare an interface extending 'AutoMigrationSpec',

Bom dia a todos

Eu tava fazendo a migration da 3 para a 4, mas um erro me aconteceu na hora de compilar:

AutoMigration Failure: Please declare an interface extending 'AutoMigrationSpec',
            and annotate with the @RenameColumn or @DeleteColumn annotation to specify the
            change to be performed:
            1) RENAME:
                @RenameColumn.Entries(
                    @RenameColumn(
                        tableName = "Usuario",
                        fromColumnName = "nomeDoUsuario",
                        toColumnName = <NEW_COLUMN_NAME>
                    )
                )
            2) DELETE:
                @DeleteColumn.Entries(
                    @DeleteColumn(
                        tableName = "Usuario",
                        columnName = "nomeDoUsuario"
                    )
                )
            
e: Error occurred in KSP, check log for detail

Antes eu tinha escrito errado, mas depois eu corrigi, mas ainda apresenta esse mesmo problema:

//Com a migration corrigida:
@RenameColumn(
    tableName = "Usuario",
    fromColumnName = "nomeDoUsuario",
    toColumnName = "idUsuario"
)
class Migration3to4 : AutoMigrationSpec

E o código do resto da Database:

@Database(
    entities = [Contato::class, Usuario::class],
    version = 4,
    exportSchema = true,
    autoMigrations = [AutoMigration(2, 3),
        AutoMigration(3, 4, Migration3to4::class)]
)
@TypeConverters(Converters::class)
abstract class HelloAppDatabase : RoomDatabase() {
    abstract fun contatoDao(): ContatoDao
    abstract fun usuarioDao(): UsuarioDao
}

E a classe da entity:

@Entity
data class Usuario(
    @PrimaryKey
    val idUsuario: String = "",
    val senha: String = "",
    @ColumnInfo(defaultValue = "")
    val nome: String = "",
)
3 respostas

Ps: a tabela json da versao 4 ficou assim

{
  "formatVersion": 1,
  "database": {
    "version": 4,
    "identityHash": "5b5137d3e29592a44cb8a2482ef76080",
    "entities": [
      {
        "tableName": "Contato",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nome` TEXT NOT NULL, `sobrenome` TEXT NOT NULL, `telefone` TEXT NOT NULL, `fotoPerfil` TEXT NOT NULL, `aniversario` INTEGER)",
        "fields": [
          {
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "nome",
            "columnName": "nome",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sobrenome",
            "columnName": "sobrenome",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "telefone",
            "columnName": "telefone",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "fotoPerfil",
            "columnName": "fotoPerfil",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "aniversario",
            "columnName": "aniversario",
            "affinity": "INTEGER",
            "notNull": false
          }
        ],
        "primaryKey": {
          "autoGenerate": true,
          "columnNames": [
            "id"
          ]
        },
        "indices": [],
        "foreignKeys": []
      },
      {
        "tableName": "Usuario",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`idUsuario` TEXT NOT NULL, `senha` TEXT NOT NULL, `nome` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`idUsuario`))",
        "fields": [
          {
            "fieldPath": "idUsuario",
            "columnName": "idUsuario",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "senha",
            "columnName": "senha",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "nome",
            "columnName": "nome",
            "affinity": "TEXT",
            "notNull": true,
            "defaultValue": "''"
          }
        ],
        "primaryKey": {
          "autoGenerate": false,
          "columnNames": [
            "idUsuario"
          ]
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5b5137d3e29592a44cb8a2482ef76080')"
    ]
  }
}

eu voltei para a versão 3 e refiz a versão 4. Além disso, eu percebi um erro. na hora de eu mudar a propertie nomeDoUsuario utilizando o Shift+F6, ele também alterava um código do UsuarioDao_Impl:

public final class UsuarioDao_Impl implements UsuarioDao {
//resto do código oculto
      @Override
      public void bind(SupportSQLiteStatement stmt, Usuario value) {
      // Shift+F6 acabava alterando também nesta função (getIdUsuario())
        if (value.getIdUsuario() == null) {
          stmt.bindNull(1);
        } else {
        // Shift+F6 também mudava aqui
          stmt.bindString(1, value.getIdUsuario());
        }
        if (value.getSenha() == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.getSenha());
        }
        if (value.getNome() == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.getNome());
        }
      }
    };
  }

Será que só de eu ter voltado para versão 3 e tentado o 4 foi o suficiente? Ou o fato de não ter alterado o código da classe UsuarioDao_Impl é que foi o decisivo?

solução!

Olá, Murilo!

Pelo que entendi, você está enfrentando um problema ao realizar a migração do banco de dados com o Room no Jetpack Compose. O erro que você está recebendo indica que é necessário declarar uma interface que estenda 'AutoMigrationSpec' e anotá-la com '@RenameColumn' ou '@DeleteColumn' para especificar a alteração a ser realizada.

Para resolver esse problema, você precisa criar uma classe que estenda 'AutoMigrationSpec' e anotá-la com '@RenameColumn' para renomear a coluna desejada. No seu caso, você está renomeando a coluna 'nomeDoUsuario' para 'idUsuario'. Portanto, você pode fazer o seguinte:

@RenameColumn(
    tableName = "Usuario",
    fromColumnName = "nomeDoUsuario",
    toColumnName = "idUsuario"
)
class Migration3to4 : AutoMigrationSpec

Certifique-se de que essa classe esteja no mesmo arquivo em que você define o banco de dados, antes da declaração da classe HelloAppDatabase.

Além disso, você precisa adicionar essa nova migração à lista de autoMigrations na anotação @Database. No seu caso, você já adicionou a migração de 3 para 4, então basta adicionar a nova migração da seguinte forma:

@Database(
    entities = [Contato::class, Usuario::class],
    version = 4,
    exportSchema = true,
    autoMigrations = [AutoMigration(2, 3),
        AutoMigration(3, 4, Migration3to4::class)]
)
@TypeConverters(Converters::class)
abstract class HelloAppDatabase : RoomDatabase() {
    abstract fun contatoDao(): ContatoDao
    abstract fun usuarioDao(): UsuarioDao
}

Com essas alterações, você deve conseguir realizar a migração do banco de dados sem problemas.

Espero ter ajudado e bons estudos!