Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 无法使用@PrimaryKey(autoGenerate=true)进行更新_Android_Sqlite_Android Room - Fatal编程技术网

Android 无法使用@PrimaryKey(autoGenerate=true)进行更新

Android 无法使用@PrimaryKey(autoGenerate=true)进行更新,android,sqlite,android-room,Android,Sqlite,Android Room,我正在使用Room,发现将主键设置为“自动生成”有问题 @PrimaryKey(自动生成=真) 如果执行插入操作,然后再执行更新操作,则这些操作生成的键会有所不同,因此,我的数据不会得到更新 @Entity(tableName = "test_table") public class TestEntity { @PrimaryKey(autoGenerate = true) private int uid; @ColumnInfo(name = "expiration

我正在使用Room,发现将主键设置为“自动生成”有问题

@PrimaryKey(自动生成=真)

如果执行插入操作,然后再执行更新操作,则这些操作生成的键会有所不同,因此,我的数据不会得到更新

@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;
    }
}
下面是一个例子

@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);
}
我已经将我的LiveData连接到了我的存储库,然而,出于以下过于简单的原因,我也执行了相同的操作

Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                // update database tables
               TestEntity testEntity = new TestEntity();
               // if I uncomment setting uid, which is the hardcoded primary key
               // value, the update will happen. If I do not include this, and 
               // just try to update my data, a new primary key is generated and
               // the old data does not get updated.

               // testEntity.setUid(1); 
               testEntity.setExpirationDateAccessToken("12345");
               AppDatabase.getAppdatabase(context).testDao().update(testEntity);

            }
        });
我的问题是,使用@PrimaryKey(autoGenerate=true)的模式是什么??通过对主键执行以下硬编码,我可以让一切都完美工作,但我认为这不是必需的

编辑

@PrimaryKey(autoGenerate=true)
私有int uid=1;
我的问题是,使用@PrimaryKey(autoGenerate=true)的模式是什么

  • 它的简单整数从0开始,然后在添加行时递增1
我是否必须始终检索id,然后在每次更新时将其传入

  • 对。 @更新-来自文档
如果参数已经存在(通过主键检查),则该方法的实现将更新其在数据库中的参数。如果它们不存在,此选项将不会更改数据库

一定有更好的办法。有什么建议吗

  • 这取决于你的要求。 若我并没有错的话,我猜你们一直试图在表中只保存一行
@查询(“更新测试表,其中1=1”)

受保护的抽象int更新(TestEntity te)

另一条路。但是这里需要设置
uid
一些硬编码的整数。
由于您不存储多个数据,因此不需要主键约束,任何上述逻辑都可以工作。

您创建一个
TestEntity
,然后告诉Room将其保存在数据库中。此时,房间将为其分配一个自动生成的主键。然后,如果要更新特定的
TestEntity
,则必须传递一个
TestEntity
类的实例,该实例的id与数据库使用的id完全相同(该id是在实体首次保存在数据库中时自动生成的,而不是在实例化它时)

因此,您必须知道要更新的实体的id。第一次保存时,如何判断分配给它的id?您可以将
@Insert
方法改为返回一个Long,即id

@Insert
Long insert(TestEntity testEntity);

因此,只需稍作更改,您现在就可以知道数据库分配给最近保存的实体的id。然后,您可以在java中将该长度设置为实体实例,更改一些其他参数,并调用update,这将起作用,因为它们这次将具有相同的id

这就是我解决该问题的方法。我希望有一个更“自动”的过程,但似乎真的没有。必须知道id,这样即使只有一行,也可以更新正确的行。现在清楚了。谢谢这实际上是最好的答案。但我已经接受了另一个。你俩说的是同一件事,但你把它说得很好。谢谢,这很有帮助!
    @PrimaryKey(autoGenerate = true)
    private int uid = 1; <---- works with any hardcoded int value
@Insert
Long insert(TestEntity testEntity);