Room数据库存储Reservation类报错:类型转换与查询字段缺失求助
问题解决方案
一、解决places和codeQR字段无法存储的问题
Room默认不支持List<Integer>和Bitmap类型,需要添加类型转换器(TypeConverter) 将这些类型转换为数据库可识别的格式(如字符串、字节数组)。
1. 创建类型转换器类
public class Converters { // 转换List<Integer>与JSON字符串 @TypeConverter public static List<Integer> stringToIntegerList(String value) throws JSONException { List<Integer> places = new ArrayList<>(); if (value == null) return places; JSONArray jsonArray = new JSONArray(value); for (int i = 0; i < jsonArray.length(); i++) { places.add(jsonArray.getInt(i)); } return places; } @TypeConverter public static String integerListToString(List<Integer> list) { JSONArray jsonArray = new JSONArray(list); return jsonArray.toString(); } // 转换Bitmap与字节数组 @TypeConverter public static Bitmap byteArrayToBitmap(byte[] bytes) { if (bytes == null) return null; return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } @TypeConverter public static byte[] bitmapToByteArray(Bitmap bitmap) { if (bitmap == null) return null; ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); return stream.toByteArray(); } }
2. 在Room数据库类中注册转换器
在你的AppDatabase类上添加@TypeConverters注解,让Room识别这些转换器:
@Database(entities = {Reservation.class, Film.class, UtilizatorMADA.class}, version = 2) @TypeConverters(Converters.class) public abstract class AppDatabase extends RoomDatabase { public abstract ReservationOfMoviesDao reservationDao(); // 其他Dao定义... }
二、解决查询缺少idFilm字段的问题
错误根源是Reservation类用@Embedded嵌入了Film实体,但Film本身是独立的数据库表,导致查询结果无法映射到ReservationMovie。正确做法是用外键关联Film,而非嵌入,再通过@Relation关联两张表的数据。
1. 修改Reservation类,用外键关联Film
去掉@Embedded Film,添加idFilm字段作为外键关联films表:
@Entity(tableName = "reservations", foreignKeys = { @ForeignKey(entity = UtilizatorMADA.class, parentColumns = "id", childColumns = "idUser"), @ForeignKey(entity = Film.class, parentColumns = "idFilm", childColumns = "idFilm") }) public class Reservation implements Serializable { @PrimaryKey(autoGenerate = true) private long idReservation; private long idUser; private int idFilm; // 关联films表的idFilm private Time startTime; private List<Integer> places; private Bitmap codeQR; // 更新构造方法,替换Film参数为idFilm public Reservation(long idReservation, long idUser, int idFilm, Time startTime, List<Integer> places, Bitmap codeQR) { this.idReservation = idReservation; this.idUser = idUser; this.idFilm = idFilm; this.startTime = startTime; this.places = places; this.codeQR = codeQR; } @Ignore public Reservation(long idUser, int idFilm, Time startTime, List<Integer> places, Bitmap codeQR) { this.idUser = idUser; this.idFilm = idFilm; this.startTime = startTime; this.places = places; this.codeQR = codeQR; } // 添加idFilm的getter/setter public int getIdFilm() { return idFilm; } public void setIdFilm(int idFilm) { this.idFilm = idFilm; } // 其他原有getter/setter不变... }
2. 创建ReservationMovie关联类
用于组合Reservation和对应的Film数据:
public class ReservationMovie { @Embedded private Reservation reservation; @Relation( parentColumn = "idFilm", entityColumn = "idFilm" ) private Film film; // 构造方法与getter/setter public ReservationMovie(Reservation reservation, Film film) { this.reservation = reservation; this.film = film; } public Reservation getReservation() { return reservation; } public void setReservation(Reservation reservation) { this.reservation = reservation; } public Film getFilm() { return film; } public void setFilm(Film film) { this.film = film; } }
3. 更新Dao接口
调整插入方法为插入Reservation,查询逻辑保持不变(Room会通过@Transaction和@Relation自动关联两张表):
@Dao public interface ReservationOfMoviesDao { @Insert(onConflict = OnConflictStrategy.IGNORE) void insert(Reservation reservation); @Transaction @Query("SELECT * FROM reservations where idUser = :id") List<ReservationMovie> getReservationOfMoviesByUserId(long id); @Transaction @Query("SELECT * FROM reservations") List<ReservationMovie> getReservationOfMovies(); @Transaction @Query("SELECT * FROM reservations where idReservation = :id") ReservationMovie getReservationOfMoviesByReservationId(long id); }
注意事项
- 如果之前已创建过数据库,需将
AppDatabase的版本号升级(如从1改为2),或卸载应用重新安装,避免表结构不匹配报错。
内容的提问来源于stack exchange,提问作者Dvalin
相关产品推荐
相关产品推荐

