Android Room DAO无法识别DatabaseView问题求助
Android Room视图查询异常:Database Inspector可查但DAO找不到视图
问题描述
Database Inspector可正常执行视图查询,但Room在DAO中无法找到对应视图,始终报错。已尝试升级数据库版本、重建视图、清理重建项目及设置viewName属性,问题仍未解决。
原始代码
视图类
package Vistas; import androidx.room.DatabaseView; @DatabaseView("SELECT Alumno.id_alumno,Alumno.primer_apellido_alumno,Alumno.segundo_apellido_alumno,Alumno.nombre_alumno,Matricula.ano_matricula, Grado.nombre_grado FROM Alumno JOIN Matricula ON Alumno.id_alumno = Matricula.id_alumno_matricula JOIN Grado ON Grado.id_grado = Matricula.id_grado_matricula") public class AlumnoVista { public Integer alumnoId; public String primerApellido; public String segundoApellido; public String nombreAlumno; public String nombreGrado; public Integer anoMatricula; }
数据库类
package Controlador; import android.content.Context; import androidx.annotation.NonNull; import androidx.room.DatabaseConfiguration; import androidx.room.InvalidationTracker; import androidx.room.Room; import androidx.room.RoomDatabase; import androidx.sqlite.db.SupportSQLiteOpenHelper; import Vistas.AlumnoVista; import entidades.Alumno; import entidades.Asignatura; import entidades.Centro; import entidades.Grado; import entidades.Matricula; import entidades.Nota; import entidades.Profesor; import entidades.Usuario; import entidadesDao.AlumnoDao; import entidadesDao.AsignaturaDao; import entidadesDao.CentroDao; import entidadesDao.MatriculaDao; import entidadesDao.NotaDao; import entidadesDao.ProfesorDao; import entidadesDao.UsuarioDao; import entidadesDao.GradoDao; @androidx.room.Database(entities = {Alumno.class, Asignatura.class, Centro.class, Profesor.class, Usuario.class, Nota.class, Matricula.class, Grado.class}, views = {AlumnoVista.class}, version=5, exportSchema = false) public abstract class BaseDatos extends RoomDatabase { private static final String DB_NAME = "database"; private static BaseDatos instance; public abstract AlumnoDao alumnoDao(); public abstract GradoDao gradoDao(); public abstract CentroDao centroDao(); public abstract AsignaturaDao asignaturaDao(); public abstract ProfesorDao profesorDao(); public abstract UsuarioDao usuarioDao(); public abstract MatriculaDao matriculaDao(); public abstract NotaDao notaDao(); public static BaseDatos getInstance(Context context) { if (instance == null){ instance = Room.databaseBuilder(context.getApplicationContext(), BaseDatos.class, DB_NAME).fallbackToDestructiveMigration().createFromAsset("database.db").build(); } return instance; } @Override public void clearAllTables() { } @NonNull @Override protected InvalidationTracker createInvalidationTracker() { return null; } @NonNull @Override protected SupportSQLiteOpenHelper createOpenHelper(@NonNull DatabaseConfiguration databaseConfiguration) { return null; } }
DAO类
package entidadesDao; import androidx.room.Dao; import androidx.room.Delete; import androidx.room.Insert; import androidx.room.OnConflictStrategy; import androidx.room.Query; import androidx.room.Update; import java.util.List; import Vistas.AlumnoVista; import entidades.Alumno; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Flowable; @Dao public interface AlumnoDao { @Insert(onConflict = OnConflictStrategy.REPLACE) public Completable insertAlumno(Alumno alumno); @Update public Completable updateAlumno(Alumno alumno); @Delete public Completable deleteAlumno(Alumno alumno); @Query("SELECT * FROM Alumno ORDER BY primer_apellido_alumno ASC") public Flowable<List<Alumno>> getAlumnosByFirstName(); @Query("SELECT * FROM AlumnoVista") public List<AlumnoVista> getAlumnosVista(); }
解决方案
1. 修正视图类字段与SQL列的映射
Room默认通过字段名匹配SQL查询返回的列名,你的AlumnoVista字段名和SQL列名不匹配,需添加@ColumnInfo注解指定对应关系:
package Vistas; import androidx.room.ColumnInfo; import androidx.room.DatabaseView; @DatabaseView("SELECT Alumno.id_alumno,Alumno.primer_apellido_alumno,Alumno.segundo_apellido_alumno,Alumno.nombre_alumno,Matricula.ano_matricula, Grado.nombre_grado FROM Alumno JOIN Matricula ON Alumno.id_alumno = Matricula.id_alumno_matricula JOIN Grado ON Grado.id_grado = Matricula.id_grado_matricula") public class AlumnoVista { @ColumnInfo(name = "id_alumno") public Integer alumnoId; @ColumnInfo(name = "primer_apellido_alumno") public String primerApellido; @ColumnInfo(name = "segundo_apellido_alumno") public String segundoApellido; @ColumnInfo(name = "nombre_alumno") public String nombreAlumno; @ColumnInfo(name = "nombre_grado") public String nombreGrado; @ColumnInfo(name = "ano_matricula") public Integer anoMatricula; }
2. 检查预打包数据库中的视图
你使用createFromAsset("database.db")加载预打包数据库,Room不会自动为预打包数据库创建视图,需手动在预打包数据库中创建AlumnoVista视图,确保其结构和@DatabaseView中的SQL一致。
3. 移除RoomDatabase的无效重写方法
你的BaseDatos类重写了clearAllTables()、createInvalidationTracker()、createOpenHelper()方法,这些空实现会破坏Room的正常运行逻辑,移除后恢复Room默认行为:
package Controlador; import android.content.Context; import androidx.room.Room; import androidx.room.RoomDatabase; import Vistas.AlumnoVista; import entidades.Alumno; import entidades.Asignatura; import entidades.Centro; import entidades.Grado; import entidades.Matricula; import entidades.Nota; import entidades.Profesor; import entidades.Usuario; import entidadesDao.AlumnoDao; import entidadesDao.AsignaturaDao; import entidadesDao.CentroDao; import entidadesDao.MatriculaDao; import entidadesDao.NotaDao; import entidadesDao.ProfesorDao; import entidadesDao.UsuarioDao; import entidadesDao.GradoDao; @androidx.room.Database(entities = {Alumno.class, Asignatura.class, Centro.class, Profesor.class, Usuario.class, Nota.class, Matricula.class, Grado.class}, views = {AlumnoVista.class}, version=5, exportSchema = false) public abstract class BaseDatos extends RoomDatabase { private static final String DB_NAME = "database"; private static BaseDatos instance; public abstract AlumnoDao alumnoDao(); public abstract GradoDao gradoDao(); public abstract CentroDao centroDao(); public abstract AsignaturaDao asignaturaDao(); public abstract ProfesorDao profesorDao(); public abstract UsuarioDao usuarioDao(); public abstract MatriculaDao matriculaDao(); public abstract NotaDao notaDao(); public static BaseDatos getInstance(Context context) { if (instance == null){ instance = Room.databaseBuilder(context.getApplicationContext(), BaseDatos.class, DB_NAME) .fallbackToDestructiveMigration() .createFromAsset("database.db") .build(); } return instance; } }
4. 统一DAO方法的返回类型
为避免线程问题,建议getAlumnosVista()方法使用RxJava的Flowable类型,和其他方法保持一致:
@Query("SELECT * FROM AlumnoVista") public Flowable<List<AlumnoVista>> getAlumnosVista();
内容的提问来源于stack exchange,提问作者JonnerBill
相关产品推荐
相关产品推荐

