Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.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 当我要在文件室中存储数据时,NOTNULL约束失败_Android_Sql_One To Many_Android Room_Dao - Fatal编程技术网

Android 当我要在文件室中存储数据时,NOTNULL约束失败

Android 当我要在文件室中存储数据时,NOTNULL约束失败,android,sql,one-to-many,android-room,dao,Android,Sql,One To Many,Android Room,Dao,我尝试为我的应用建立离线支持。以下是我运行应用程序时出现的异常错误: 2019-04-19 13:44:44.768 8549-8549/com.sample.android.superhero E/AndroidRuntime: FATAL EXCEPTION: main Process: com.sample.android.superhero, PID: 8549 android.database.sqlite.SQLiteConstraintException: NOT

我尝试为我的应用建立离线支持。以下是我运行应用程序时出现的异常错误:

2019-04-19 13:44:44.768 8549-8549/com.sample.android.superhero E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.sample.android.superhero, PID: 8549
    android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: heroes.power_id (code 1299)
    #################################################################
    Error Code : 1299 (SQLITE_CONSTRAINT_NOTNULL)
    Caused By : Abort due to constraint violation.
        (NOT NULL constraint failed: heroes.power_id (code 1299))
    #################################################################
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:953)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
        at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
        at com.sample.android.superhero.data.source.local.HeroDao_Impl.insertHero(HeroDao_Impl.java:189)
        at com.sample.android.superhero.data.source.local.SuperHeroLocalDataSource$saveHero$2.invokeSuspend(SuperHeroLocalDataSource.kt:27)
        at com.sample.android.superhero.data.source.local.SuperHeroLocalDataSource$saveHero$2.invoke(Unknown Source:10)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:146)
        at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
        at com.sample.android.superhero.data.source.local.SuperHeroLocalDataSource.saveHero(SuperHeroLocalDataSource.kt:26)
        at com.sample.android.superhero.data.source.SuperHeroRepository.refreshLocalDataSource(SuperHeroRepository.kt:55)
        at com.sample.android.superhero.data.source.SuperHeroRepository.getHeroesFromRemoteDataSource(SuperHeroRepository.kt:45)
        at com.sample.android.superhero.data.source.SuperHeroRepository$getHeroesFromRemoteDataSource$1.invokeSuspend(Unknown Source:12)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.ResumeModeKt.resumeUninterceptedMode(ResumeMode.kt:46)
        at kotlinx.coroutines.internal.ScopeCoroutine.onCompletionInternal$kotlinx_coroutines_core(Scopes.kt:28)
        at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:305)
        at kotlinx.coroutines.JobSupport.tryFinalizeSimpleState(JobSupport.kt:264)
        at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:762)
        at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:742)
        at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:117)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
        at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
我的英雄模型如下:

@Entity(tableName = "heroes")
class Hero(
    @PrimaryKey @ColumnInfo(name = "entryid")
    val id: String,
    val name: String,
    @Embedded(prefix = "power_")
    val power: Powerstates,
    @Embedded(prefix = "bio_")
    val bio: Biography,
    @Embedded(prefix = "appearance_")
    val appearance: Appearance,
    @Embedded(prefix = "work_")
    val work: Work,
    @Embedded
    val image: Image
)
以下是我的电源模型:

@Entity(
    tableName = "powerstates",
    foreignKeys = [
        ForeignKey(
            entity = Hero::class,
            parentColumns = ["entryid"],
            childColumns = ["heroId"],
            onDelete = ForeignKey.CASCADE
        )], indices = [Index("heroId")]
)
class Powerstates(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val heroId: Int,
    val intelligence: Int,
    val strength: Int,
    val speed: Int,
    val power: Int,
    val combat: Int
)
以下是保存和检索数据的逻辑:

override suspend fun getHeroes(query: String): Result<List<Hero>> {
        return if (cacheIsDirty) {
            // If the cache is dirty we need to fetch new data from the network.
            getHeroesFromRemoteDataSource(query)
        } else {
            // Query the local storage if available. If not, query the network.
            when (val result = localDataSource.getHeroes(query)) {
                is Result.Success -> Result.Success(result.data)
                is Result.Error -> getHeroesFromRemoteDataSource(query)
            }
        }
    }

    private suspend fun getHeroesFromRemoteDataSource(query: String): Result<List<Hero>> {
        return when (val result = remoteDataSource.getHeroes(query)) {
            is Result.Success -> {
                refreshLocalDataSource(result.data)
                Result.Success(result.data)
            }
            is Result.Error -> Result.Error(result.exception)
        }
    }

    private suspend fun refreshLocalDataSource(heroes: List<Hero>) {
        localDataSource.deleteAllHeroes()
        for (hero in heroes) {
            localDataSource.saveHero(hero)
        }
    }

您正在将
Powerstates
用作
@嵌入的
对象,而不是单独的实体。因此,从
Powerstates
中删除
@PrimaryKey
@Entity
,以及(显然)不必要的列。你应该以以下方式结束:

class Powerstates(
    val intelligence: Int,
    val strength: Int,
    val speed: Int,
    val power: Int,
    val combat: Int
)

正如Commonware提到的:您可能希望查看生成的房间代码(堆栈跟踪中列出的类),并查看可能出现的问题公用软件


最好是调试生成的代码,您将获得所需的信息。在我的情况下,它很有帮助。

谢谢你的回答@commonware,现在我收到以下异常:
(非空约束失败:heros.intelligence(代码1299))
@Ali:因为它是一个
Int
,我不知道它怎么会是
NULL
。您可能希望查看生成的房间代码(堆栈跟踪中列出的类),并查看可能出现的问题。
class Powerstates(
    val intelligence: Int,
    val strength: Int,
    val speed: Int,
    val power: Int,
    val combat: Int
)