Android Room疑问:删除Book实体时为何Author实体也被删除?
问题原因分析与解决
首先明确:按照你当前的外键配置,删除BookEntity本身不会触发AuthorEntity的删除。你的关联表author_book作为子表,外键分别指向Author和Book两个父表,onDelete = ForeignKey.CASCADE的作用是:当父表(比如Book)的行被删除时,子表(关联表)中对应的关联行自动删除,父表Author不会受到任何影响。
出现AuthorEntity被误删的情况,大概率是以下操作层面的问题:
1. 调用了错误的删除方法
你可能误执行了删除AuthorEntity的DAO方法,而非删除BookEntity的方法。比如:
// 错误:删除Author,触发关联表CASCADE删除,你误以为是删除Book的操作 dao.deleteAuthor(targetAuthorId)
而正确的删除Book操作应该是:
// 正确:仅删除Book,关联表对应行自动CASCADE删除 dao.deleteBook(targetBookId)
2. 自定义删除SQL写错
如果用@Query自定义删除语句,可能不小心包含了对Author表的删除逻辑。比如错误的SQL:
@Query("DELETE FROM author, book WHERE book.bookId = :bookId") fun deleteBook(bookId: String)
这种写法会同时删除Book和关联的Author,完全偏离了你的预期。
3. 误用关联实体的删除操作
如果你通过NewsWithSectionWithContract这个关联实体执行删除(比如DAO中定义了@Delete fun delete(authorWithBooks: NewsWithSectionWithContract)),Room会默认删除@Embedded标注的AuthorEntity,进而触发关联表的CASCADE删除。如果你的业务逻辑中是在删除Book时调用了这个方法,就会导致Author被误删。
正确的处理方式
- 确保DAO中删除Book的方法仅针对
BookEntity:
@Dao interface BookDao { @Delete fun deleteBook(book: BookEntity) @Query("DELETE FROM book WHERE bookId = :bookId") fun deleteBookById(bookId: String) }
- 保留当前的外键配置即可,它的逻辑是正确的:删除Book时,关联表中对应的
(authorId, bookId)行会自动被CASCADE删除,Author表不受影响。
内容的提问来源于stack exchange,提问作者Sbirulinu
相关产品推荐
相关产品推荐

