You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:24:31