es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Flutter Hive no guarda subclases.

Digamos que tengo las siguientes 3 clases:

class Human {
  String name;

  Human({this.name});
}

class Student extends Human {
  int id;

  Student(this.id) : super(name: name);
}

class Professor extends Human {
  int age;

  Professor(this.age) : super(name: name);
}

class Abc {
  List<human> humans;

  Abc(this.humans);
}

Estoy utilizando las siguientes dependencias:

hive_generator: ^1.1.1
hive_flutter: ^1.1.0
hive: ^2.0.4
dev_dependencies:
  build_runner: ^2.1.4

Básicamente, tengo una lista <human> que consta de Professors y Students, pero cuando esta lista se guarda y luego se recupera de Hive, todos los objetos en esa lista se convierten a Human.

Abc read(BinaryReader reader) {
  final numOfFields = reader.readByte();

  final fields = <int, dynamic="">{
    for (int i = 0; i < numOfFields; i++)
      reader.readByte(): reader.read(),
  };

  return Abc(
    fields[0] as int,
    fields[1] as String?,
    fields[2] as String?,
    (fields[3] as List?)?.cast<human>(), // Necesito los elementos de esta lista como Student / Professor, no como Humanos
    fields[4] as int,
  );
}

Básicamente, estoy perdiendo información porque los estudiantes y profesores se convierten en humanos mediante el adaptador.

¿Hay alguna solución a esto? Si no, ¿cuál es la mejor alternativa a hive?</int,>

Tags:  ,

Answer

  1. Avatar for davy.ai

    Sí, hay una solución alternativa para este problema en Hive. Debes crear un adaptador separado para cada subtipo de Human (Estudiante y Profesor) y luego registrar esos adaptadores con Hive. Así es cómo puedes modificar tu código para que funcione:

    class StudentAdapter extends TypeAdapter<student> {
      @override
      Student read(BinaryReader reader) {
        final id = reader.readInt();
        final name = reader.readString();
        return Student(id)..name = name;
      }
    
      @override
      void write(BinaryWriter writer, Student obj) {
        writer.writeInt(obj.id);
        writer.writeString(obj.name);
      }
    
      @override
      int get typeId => 0; // ID único para este adaptador
    }
    
    class ProfessorAdapter extends TypeAdapter<professor> {
      @override
      Professor read(BinaryReader reader) {
        final age = reader.readInt();
        final name = reader.readString();
        return Professor(age)..name = name;
      }
    
      @override
      void write(BinaryWriter writer, Professor obj) {
        writer.writeInt(obj.age);
        writer.writeString(obj.name);
      }
    
      @override
      int get typeId => 1; // ID único para este adaptador
    }
    
    // Registrar los adaptadores con Hive
    void main() async {
      await Hive.initFlutter();
      Hive.registerAdapter(StudentAdapter());
      Hive.registerAdapter(ProfessorAdapter());
    }
    
    // Utilizar las clases de subtipo en lugar de Human en la clase Abc
    class Abc {
      List<student> students;
      List<professor> professors;
    
      Abc({required this.students, required this.professors});
    }
    

    En este código, definimos dos adaptadores separados para las clases Student y Professor. Estos adaptadores son responsables de leer y escribir objetos de sus respectivos tipos a datos binarios, que es lo que Hive utiliza para almacenar datos en el disco.

    También modificamos la clase Abc para utilizar las clases de subtipo (Student y Professor) en lugar de la clase Human. De esta manera, cuando guardemos un objeto Abc en Hive, automáticamente utilizará los adaptadores registrados para convertir los objetos Student y Professor a datos binarios de manera correcta.

    Con este enfoque, no perderás ninguna información al leer datos desde Hive. Puedes recuperar el objeto Abc como de costumbre y todos los elementos en las listas students y professors serán de sus respectivos subtipos.

    Si Hive no funciona bien para tu caso de uso, puedes considerar utilizar otras soluciones de bases de datos populares para Flutter, como SQLite o Firebase.

Comments are closed.