我正在与Room一起工作,但发现将主键设置为自动生成时出现了问题,
@PrimaryKey(autoGenerate = true)
如果我先执行INSERT操作,然后再执行UPDATE操作,则这些操作生成的密钥会有所不同,因此我的数据不会得到更新。
NullPointerException
这是DAO的示例
Room newRoom = new Room();
newRoom.setName(meetingRoom[0]);
newRoom.setCode(meetingRoom[1]);
few more setters ...
home.addRoom(newRoom);
这是我的AppDatabase
@Entity(tableName = "test_table")
public class TestEntity {
@PrimaryKey(autoGenerate = true)
private int uid;
@ColumnInfo(name = "expiration_date_access_token")
private String expirationDateAccessToken;
/**
* Getter for retrieving primary key
*
* @return Primary key
*/
public int getUid() {
return uid;
}
/**
* Setter for setting primary key
*
* @param uid Primary key
*/
public void setUid(int uid) {
this.uid = uid;
}
/**
* Getter for retrieving expiration date of access token
*
* @return Expiration date of access token
*/
public String getExpirationDateAccessToken() {
return expirationDateAccessToken;
}
/**
* Setter for setting expiration date of access token
*
* @param expirationDateAccessToken Expiration date of access token
*/
public void setExpirationDateAccessToken(String expirationDateAccessToken) {
this.expirationDateAccessToken = expirationDateAccessToken;
}
}
但是,由于以下简单的原因,我已将LiveData连接到我的存储库。
@Dao
public interface TestDao {
@Query("SELECT * FROM test_table")
List<TestEntity> getAll();
@Query("DELETE FROM test_table")
void deleteAll();
@Insert
void insert(TestEntity testEntity);
@Delete
void delete(TestEntity testEntity);
@Update
void update(TestEntity testEntity);
}
我的问题是,使用@PrimaryKey(autoGenerate = true)的模式是什么?通过对主键进行以下硬编码,我可以使一切正常工作,但是我认为这不是必需的。
编辑
@Database(entities = {TestEntity.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static final String DATABASE_NAME = "room.test.db";
private static AppDatabase APP_DATABASE_INSTANCE;
public abstract TestDao testDao();
public static AppDatabase getAppdatabase(@NonNull Context context) {
if (FrameworkUtils.checkIfNull(APP_DATABASE_INSTANCE)) {
APP_DATABASE_INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, DATABASE_NAME).build();
}
return APP_DATABASE_INSTANCE;
}
/**
* Method is used to destroy database instance
*/
public static void destroy() {
APP_DATABASE_INSTANCE = null;
}
}
答案 0 :(得分:2)
您创建一个TestEntity
,然后告诉Room将其保存在数据库中。此时,Room为其分配了一个自动生成的主键。如果要更新特定的TestEntity
,则必须传递TestEntity
类的实例,该实例的ID与数据库使用的ID完全相同(在为该实体保存实体时会自动生成该ID)第一次在数据库中,而不是在实例化时。)
因此,您必须知道要更新的实体的ID。首次保存时,如何知道分配给哪个ID?您可以使您的@Insert
方法返回一个Long,它是id。
@Insert
Long insert(TestEntity testEntity);
因此,只需进行很小的更改,您现在就可以知道数据库分配给最近保存的实体的ID。然后,您可以在Java中将Long设置为Entity实例,更改其他参数,然后调用update,因为它这次具有相同的ID,所以它将起作用
答案 1 :(得分:1)
我的问题是,使用@PrimaryKey(autoGenerate = true)的模式是什么?
我是否必须始终检索ID,然后在每次更新时都将其传入?
该方法的实现将更新其在数据库中的参数(如果它们已经存在)(通过主键检查)。如果它们尚不存在,则此选项将不会更改数据库。
必须有更好的方法。有什么建议吗?
@Query(“ UPDATE test_table where 1 = 1”)
受保护的抽象int update(TestEntity te);
替代方式。但是在这里,您需要设置uid
一些硬编码的整数。
由于您不存储多个,所以不需要主键约束,上述任何逻辑都将起作用。