Room实体中SQLite NULL值为何转为0?字段映射问题求助
问题描述
我在SQLite数据库中定义了如下表:
CREATE TABLE `lh_psalm_join` ( `groupFK` INTEGER NOT NULL, `readingFK` INTEGER NOT NULL, `theOrder` INTEGER NOT NULL, `themeFK` INTEGER DEFAULT NULL, `epigraphFK` INTEGER DEFAULT NULL, `thePart` INTEGER DEFAULT NULL, PRIMARY KEY (`groupFK`, `readingFK`), FOREIGN KEY(`groupFK`) REFERENCES `lh_psalmody_join`(`groupID`) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY(`readingFK`) REFERENCES `lh_psalm`(`psalmID`) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY(`epigraphFK`) REFERENCES `lh_epigraph`(`epigraphID`) ON DELETE SET NULL ON UPDATE CASCADE, FOREIGN KEY(`themeFK`) REFERENCES `lh_theme`(`themeID`) ON DELETE SET NULL ON UPDATE CASCADE );
我在Room实体中将thePart字段定义为:
@ColumnInfo(name = "thePart", defaultValue = "NULL") var thePart: Int?
但读取数据时,数据库中thePart为NULL的值,在实体中却变成了0。我通过如下判断发现了这个问题——该判断始终返回true:
if (thePart != null || thePart !=0)
请问Room会将NULL值转换为0吗?仅用if (myValue != 0)进行判断是否可行?我查阅了Room官方文档,但未找到相关说明。
解答
Room本身不会把SQLite的NULL自动转成0,你遇到的情况首先得排查判断逻辑的问题——你写的if (thePart != null || thePart !=0)本身逻辑就有问题:如果thePart是0,thePart != null为true;如果是null,thePart !=0也为true,所以不管怎样都会返回true,这才是判断始终成立的核心原因,不是NULL被转成了0。
再回到你的核心疑问:
- 对于标记为可空的
Int?字段,Room读取SQLite的NULL时,应该会正确映射为Kotlin的null,不会自动转为0。如果实体里出现0,大概率是插入/更新数据时不小心给thePart设了0,或者查询语句里用了COALESCE这类默认补0的函数。 - 仅用
if (myValue != 0)绝对不可行:如果数据库里是NULL,映射到实体是null,此时myValue !=0会因为null和0比较返回true,完全无法区分“实际值非0”和“值为null”的场景。正确的判断应该先检查是否为null,再判断是否不等于0,比如:
if (thePart != null && thePart != 0)
你也可以直接打印thePart的实际值,直观确认到底是null还是0,这样能更快定位问题。
内容的提问来源于stack exchange,提问作者A. Cedano
相关产品推荐
相关产品推荐

