update数据库时出现不存在的列:Unknown column name 'serialVersionUID' in table

博客指出查看表未实现实例化接口,反射发现多出$change和serialVersionUID属性,这是AndroidStudio开启InstantRun时序列化操作导致。关闭InstantRun可解决部分问题,同时因底层封装数据库不严谨,反射获取列时会受影响,还给出修改框架根据注解获取列的解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查看该表,发现并没有实现实例化接口。
通过下面方法反射出所有的属性,发现确实多了一个$change 和一个serialVersionUID。

public static void showAnnotationWrodOther(){
        Field[] fields = DbApp.class.getFields();
        for (Field field : fields) {
            field.setAccessible(true);
            LogUtil.d("DbAppfield  getFields name = " + field.getName());
        }
        fields = DbApp.class.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            LogUtil.d("DbAppfield  getDeclaredFields name = " + field.getName());
        }
}

change.png

通过查阅资料,AndroidStudio开启InstantRun时会出现这种情况。过程存在序列化操作。所以关闭InstantRun。
File>Settings>Instant Run 选项全部关闭。
猜测热修复也可能会有这种情况?(不确定)

但是一般情况下,多出的这两个属性不应该会影响插入数据库。但是我们底层封装数据库的时候并不严谨。
是通过反射获取的所有不为空的属性作为表列。所以也会把这个属性认为是存在的列。

解决办法:
1.关闭Instant Run
2.修改框架,根据是否有DatabaseField注解来获取对应的列。field.isAnnotationPresent(DatabaseField.class);

Java 序化是指将 Java 对象的状态转换为可存储或传输的格式(如字节流)的过程,以便可以在网络上传输这些对象,或者将对象的状态持久化到文件中。反序化则是将这些字节流重新转换为 Java 对象的过程。这一机制在远程方法调用(RMI)、分布式系统和对象持久化中非常有用。 ### 实现方式 Java 提供了内置的序化机制,主要通过 `java.io.Serializable` 接口和 `ObjectOutputStream`、`ObjectInputStream` 类来实现。 #### 1. 实现 `Serializable` 接口 要使一个类的对象可以序化,该类需要实现 `Serializable` 接口。这个接口是一个标记接口,没有需要实现的方法。例如: ```java import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters and setters } ``` #### 2. 序化对象 使用 `ObjectOutputStream` 类将对象写入文件或输出流: ```java import java.io.FileOutputStream; import java.io.ObjectOutputStream; public class SerializeExample { public static void main(String[] args) { Person person = new Person("John Doe", 30); try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) { oos.writeObject(person); System.out.println("对象已序化"); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 3. 反序化对象 使用 `ObjectInputStream` 类从文件或输入流中读取对象: ```java import java.io.FileInputStream; import java.io.ObjectInputStream; public class DeserializeExample { public static void main(String[] args) { try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) { Person person = (Person) ois.readObject(); System.out.println("对象已反序: " + person.getName() + ", " + person.getAge()); } catch (Exception e) { e.printStackTrace(); } } } ``` ### 注意事项 - **`serialVersionUID`**:每个可序化的类都应该显式定义 `serialVersionUID`,以确保在反序版本一致。如果定义,Java 会根据类的结构自动生成,但类的任何变化都会导致 `serialVersionUID` 改变,从而引发 `InvalidClassException`。 - **静态字段和瞬态字段**:静态字段会被序化,因为它们属于类而是对象。如果某些字段需要序化,可以使用 `transient` 关键字修饰。 ### 其他序化方式 除了 Java 内置的序化机制,还可以使用其他框架或库来实现更高效的序化,例如: - **Google Protocol Buffers**:一种高效的二进制序化框架。 - **Apache Avro**:支持模式演化的序化框架。 - **JSON**:使用 `Jackson` 或 `Gson` 等库将对象序化为 JSON 格式。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值