-
-
Notifications
You must be signed in to change notification settings - Fork 30
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Error log (truncated for clarity)
java.lang.IllegalStateException: The query result was empty, but expected a single row to return a NON-NULL object of type <com.ethran.notable.data.db.Folder>.
at com.ethran.notable.data.db.FolderDao_Impl.get$lambda$0(FolderDao_Impl.kt:221)
at com.ethran.notable.data.db.FolderDao_Impl.get(FolderDao_Impl.kt:171)
at com.ethran.notable.data.db.FolderRepository.get(Folder.kt:79)
at com.ethran.notable.ui.components.BreadCrumbKt.getFolderList(BreadCrumb.kt:74)
at com.ethran.notable.ui.components.BreadCrumbKt.BreadCrumb(BreadCrumb.kt:51)
at com.ethran.notable.ui.views.HomeViewKt.Library(HomeView.kt:138)
Possible cause
A DAO/repository call expected a non-null Folder but the query returned no rows. The DAO signature returns a non-null Folder, so a missing row results in IllegalStateException. This may happen if a folder ID is stale/missing or was deleted.
Referenced code
- Folder entity, DAO and repository (DAO returns non-null; repository uses it):
- Folder.kt (includes DAO and repository; repository get and DAO get):
notable/app/src/main/java/com/ethran/notable/data/db/Folder.kt
Lines 1 to 87 in e6c2af5
package com.ethran.notable.data.db import android.content.Context import androidx.lifecycle.LiveData import androidx.room.ColumnInfo import androidx.room.Dao import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.Insert import androidx.room.PrimaryKey import androidx.room.Query import androidx.room.Update import java.util.Date import java.util.UUID @Entity( foreignKeys = [ForeignKey( entity = Folder::class, parentColumns = arrayOf("id"), childColumns = arrayOf("parentFolderId"), onDelete = ForeignKey.CASCADE )] ) data class Folder( @PrimaryKey val id: String = UUID.randomUUID().toString(), val title: String = "New Folder", @ColumnInfo(index = true) val parentFolderId: String? = null, val createdAt: Date = Date(), val updatedAt: Date = Date() ) // DAO @Dao interface FolderDao { @Query("SELECT * FROM folder WHERE parentFolderId IS :folderId") fun getChildrenFolders(folderId: String?): LiveData<List<Folder>> @Query("SELECT * FROM folder WHERE id IS :folderId") fun get(folderId: String): Folder @Insert fun create(folder: Folder): Long @Update fun update(folder: Folder) @Query("DELETE FROM folder WHERE id=:id") fun delete(id: String) } class FolderRepository(context: Context) { var db = AppDatabase.getDatabase(context).folderDao() fun create(folder: Folder) { db.create(folder) } fun update(folder: Folder) { db.update(folder) } fun getAllInFolder(folderId: String? = null): LiveData<List<Folder>> { return db.getChildrenFolders(folderId) } fun getParent(folderId: String? = null): String? { if (folderId == null) return null val folder = db.get(folderId) return folder.parentFolderId } fun get(folderId: String): Folder { return db.get(folderId) } fun delete(id: String) { db.delete(id) } } - Specific repository call site (FolderRepository.get):
return db.get(folderId)
- Folder.kt (includes DAO and repository; repository get and DAO get):
- BreadCrumb usage path:
- getFolderList (calls FolderRepository.get and recurses):
fun getFolderList(context: Context, folderId: String): List<Folder> { @Suppress("USELESS_ELVIS") val folder = FolderRepository(context).get(folderId) ?: return emptyList() val folderList = mutableListOf(folder) val parentId = folder.parentFolderId if (parentId != null) { folderList.addAll(getFolderList(context, parentId)) } return folderList } - BreadCrumb composable:
package com.ethran.notable.ui.components import android.content.Context import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.material.Icon import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ChevronRight import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.ethran.notable.R import com.ethran.notable.data.db.Folder import com.ethran.notable.data.db.FolderRepository import com.ethran.notable.ui.noRippleClickable @Composable fun BreadCrumb( modifier: Modifier = Modifier, folderId: String? = null, fontSize: Int = 20, onSelectFolderId: (String?) -> Unit ) { val context = LocalContext.current Row( modifier = modifier.padding(horizontal = 8.dp, vertical = 4.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp) ) { Text( text = context.getString(R.string.home_view_name), fontSize = fontSize.sp, textDecoration = TextDecoration.Underline, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier .padding(end = 2.dp) .noRippleClickable { onSelectFolderId(null) } ) // ToolbarButton(iconId = R.drawable.home, onSelect = { onSelectFolderId(null) }) if (folderId != null) { val folders: List<Folder> = getFolderList(context, folderId).reversed() folders.forEach { f -> Icon( imageVector = Icons.Filled.ChevronRight, contentDescription = null, // decorative modifier = Modifier.padding(horizontal = 2.dp) ) Text( text = f.title, fontSize = fontSize.sp, textDecoration = TextDecoration.Underline, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.noRippleClickable { onSelectFolderId(f.id) } ) } } } }
- getFolderList (calls FolderRepository.get and recurses):
- Home screen where BreadCrumb is used:
- Library composable reference line:
BreadCrumb(folderId = folderId) { navController.navigate("library" + if (it == null) "" else "?folderId=${it}") }
- Library composable reference line:
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working