android - 无法阻止 Android 房间数据库中的触发器递归
问题描述
我无法阻止房间数据库中的递归触发器。每当 RecipeEntity 通过更新触发器发生值更改时,我都会尝试将我的 RecipeEntity 表中的 is_updated 列更新为 false。
// prevent recursion
db.execSQL("PRAGMA recursive_triggers = OFF;");
// create recipe trigger to update is_updated to false every time recipe is updated
db.execSQL("CREATE TRIGGER is_updated_trigger BEFORE UPDATE" +
" ON RecipeEntity" +
" BEGIN" +
" UPDATE RecipeEntity SET is_updated=false" +
" WHERE recipeId = NEW.recipeId; " +
" END; ");
这在使用 RoomDatabase.Callback() 通过 onCreate 创建数据库时调用;
更新 RecipeEntity 的查询只是一个普通的 Room @Update 方法。
错误信息:
2021-05-25 15:03:07.422 4668-4821/com.habbybolan.groceryplanner E/SQLiteLog: (1) statement aborts at 64: [UPDATE OR ABORT `RecipeEntity` SET `recipeId` = ?,`onlineRecipeId` = ?,`name` = ?,`is_favorite` = ?,`description` = ?,`prep_time` = ?,`cook_time` = ?,`serving_size` = ?,`calories` = ?,
--------- beginning of crash
2021-05-25 15:03:07.429 4668-4821/com.habbybolan.groceryplanner E/AndroidRuntime: FATAL EXCEPTION: Thread-3
Process: com.habbybolan.groceryplanner, PID: 4668
android.database.sqlite.SQLiteException: too many levels of trigger recursion (code 1 SQLITE_ERROR)
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:890)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:756)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:66)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:46)
at androidx.room.EntityDeletionOrUpdateAdapter.handle(EntityDeletionOrUpdateAdapter.java:70)
at com.habbybolan.groceryplanner.database.dao.RecipeDao_Impl.updateRecipes(RecipeDao_Impl.java:531)
at com.habbybolan.groceryplanner.database.DatabaseAccessImpl.lambda$updateRecipe$14$DatabaseAccessImpl(DatabaseAccessImpl.java:427)
at com.habbybolan.groceryplanner.database.-$$Lambda$DatabaseAccessImpl$3OxencYWN3idP4iK5ncgMxJDuQc.run(Unknown Source:4)
at java.lang.Thread.run(Thread.java:923)
2021-05-25 15:03:07.453 1017-1023/? E/statsd: Predicate 5980654721335871649 dropping data for dimension key (10)0x2010101->10361[I] (10)0x30000->*launch*[S]
2021-05-25 15:03:07.488 1620-2075/? E/InputDispatcher: channel '99b1b43 Toast (server)' ~ Channel is unrecoverably broken and will be disposed!
出于某种原因,当我从设备下载数据库并在 DB Browser 软件中运行它时,它可以正常工作而不会导致任何触发递归。这似乎是特定于 Room 的东西?
任何见解将不胜感激。谢谢你的帮助。
解决方案
我相信你的问题是你似乎只在onCreate
回调中发出 PRAGMA 。
这个回调只会被调用一次,我不相信状态会持续存在。因此,RECURSIVE_TRIGGERS 为 ON(左为 ON)。
我建议添加一个onOpen
回调来执行 PRAGMA。
推荐阅读
- android - 如何检测Android中按下按钮的时间?
- python - OpenCV Python VideoWriter 保存损坏的视频
- unit-testing - 在 spock 中调用验证 void 方法的最佳方法是什么
- java - Java使用正则表达式替换多重字符
- ios - 具有 Swift 5 反向关系的领域在启动时使应用程序崩溃
- javascript - 如何从顺风配置文件中获取颜色值
- c# - Newtonsoft,反序列化并将json字符串元素转换为对象属性中的属性
- python - 将数据写入 Django SQL Lite DB 时遇到问题
- python - 如何将 numpy 数组重塑为具有周围像素内核的新 ndarraw
- javascript - React-Google-Maps 显示两个标记,一个在原始位置,另一个标记跟随地图的新中心 onDrag