【问题标题】:Android Room persistence SQLiteConstraintException when inserting items twice插入项目两次时的Android Room持久性SQLiteConstraintException
【发布时间】:2018-06-03 20:40:42
【问题描述】:

我一直在使用 Room 持久性库,该库一直运行良好,直到我在两个不同的插入项中添加项目。

声音实体类

@Entity
public class Sound {
@PrimaryKey(autoGenerate = true)
private int sid;
@ColumnInfo(name = "sound_theme")
private int soundTheme;
@ColumnInfo(name = "sound_name")
private String soundName;
@ColumnInfo(name = "sound_resource")
private int soundResource;
@ColumnInfo(name = "sound_image_resource")
private int soundImageResource;
@ColumnInfo(name = "sound_favorite")
private boolean isFavorite;
@ColumnInfo
private int usedCount;
@ColumnInfo
private long lastUsed;


 public Sound(int soundTheme, String soundName, int soundResource, int soundImageResource, boolean isFavorite, int usedCount, long lastUsed) {
    this.soundTheme = soundTheme;
    this.soundName = soundName;
    this.soundResource = soundResource;
    this.soundImageResource = soundImageResource;
    this.isFavorite = isFavorite;
    this.usedCount = usedCount;
    this.lastUsed = lastUsed;
}

注意我有一个健全的 id 作为自动生成的主键。

声音 DAO

@Dao
public interface SoundDao {

@Query("SELECT * FROM sound")
List<Sound> getAll();

@Query("SELECT * FROM sound WHERE sid IN (:soundIds)")
List<Sound> loadAllByIds(int[] soundIds);

@Query("SELECT * FROM sound WHERE sound_name LIKE :name LIMIT 1")
Sound findByName(String name);

@Query("SELECT * FROM sound WHERE sid LIKE :id LIMIT 1")
Sound findById(int id);

@Insert
void insertAll(Sound... sounds);

@Insert
void insertAllArrList(ArrayList<Sound> sounds);

@Delete
void delete(Sound sound);

@Query("DELETE FROM sound")
public void deleteAllSounds();
}

错误与这一行有关:

      if (focusedSound.isFavorite()) 
      favorites.soundDao().insertAll(focusedSound); 
      else favorites.soundDao().delete(selectedSound);

第一次插入顺利(如果您在其中插入多个项目也可以),第二次插入它会崩溃。 我认为它与声音 id(sid) 的主键有关,但我不确定如何解决。

这里是一些错误日志:

06-03 20:03:36.454 8807-8807/com.zaid.green.soundpress E/InputEventReceiver: 
Exception dispatching input event.
06-03 20:03:36.454 8807-8807/com.zaid.green.soundpress E/MessageQueue-JNI: 
Exception in MessageQueue callback: handleReceiveCallback
06-03 20:03:36.460 8807-8807/com.zaid.green.soundpress E/MessageQueue-JNI: 
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: 
Sound.sid (code 1555)
SQLiteConnection at nativeExecuteForLastInsertedRowId(Native Method)  
SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
    at 

【问题讨论】:

    标签: android database sqlite android-room


    【解决方案1】:

    是的,你是对的,问题在于主要约束和插入的重复项。

    解决方案:在您的 @intert 方法上将 OnConflictStratergy 定义为

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(Sound... sounds);
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAllArrList(ArrayList<Sound> sounds);
    

    如您所见,这会将新对象替换为旧对象

    【讨论】:

    • 它确实解决了这个问题,你认为这是以编程方式处理这个问题吗?否则可能会在开发过程中给我带来一些问题
    • 我刚刚继续了一点,它确实解决了问题,但新的问题是当我想在插入多个项目后删除最喜欢的项目时,它因为试图删除一个 null 的项目而崩溃ID。有没有办法处理它?因为我填的解决方案只能解决部分情况
    • hmm,您是否使用我们刚刚用来替换旧对象的新对象(同时删除),因为使用此解决方案,旧的 id 或对象不再存在
    猜你喜欢
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 2019-04-25
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多