当前位置: 首页 > 知识库问答 >
问题:

带有延迟外键的Android房间

蔡楚
2023-03-14

每当在服务器上删除福利时,我还想从Favorite福利中删除一个适当的实体。为此,我可以使用onDelete=ForeignKey。CASCADE并且每当数据库中不再存在父福利时,Favorite福利也会被删除。听起来不错。

每当我使用@Insert(onConflict=OnConflictStrategy.REPLACE)更新数据库中的福利时,就会出现问题REPLACE实际上执行DELETEINSERT操作,但是DELETE会在内部触发FavoriteBenefitonDelete,因此,该表中的所有数据也会被删除。

(类似的问题出现在优惠券usedCoon表格上。)

我正在寻找一种在事务结束前暂时禁用外键约束的方法。也就是说,不要在事务期间验证外键,而只在事务结束时验证外键。我仍然希望房间自动删除没有有效父级的实体。

似乎通过在@ForeignKey定义上设置deferred=true来将外键标记为deferred应该正是我想要实现的。

布尔延迟()

外键约束可以推迟到事务完成。如果要在单个事务中批量插入数据库,这将非常有用。默认情况下,外键约束是即时的,但您可以通过将此字段设置为true来更改它。

但是,即使我设置了deferred标志,它似乎也没有效果,因为每次都会删除FavoriteBenefit

我是否错误地理解了延迟标志?

共有3个答案

支华池
2023-03-14

我以前遇到过这个问题,我通过创建名为delsert的新语法解决了这个问题<这里有一个例子:

    @Query("DELETE FROM patient")
    public abstract void delete();

    @Query("DELETE FROM patient WHERE p_id IN (SELECT p_id FROM patient WHERE p_id NOT IN (:ids))")
    public abstract void deleteUnused(List<Long> ids);

    @Transaction
    public void delsert(List<Patient> patientList) {
        if (CommonUtils.isListEmpty(patientList)) {
            this.delete();
            return;
        }

        List<Long> idsPatient = new ArrayList<>();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
            patientList.forEach(order -> idsPatient.add(order.getId()));
        else
            for (Patient id : patientList) idsPatient.add(id.getId());

        deleteUnused(idsPatient);

        insert(patientList);
    }
赫连捷
2023-03-14

原因是ON DELETE CASCADE是一个类似触发器的操作,它会立即执行。请参阅问题和评论。

PostgreSQL团队还有更详细的解释:

是的,据我们所知,这是根据SQL规范。约束检查可以推迟到事务结束,但“引用操作”是不可推迟的。它们总是在触发语句期间发生。例如,SQL99将级联删除的结果描述为引用行立即“标记为删除”,然后

再看看类似的SQLite问题,其中包含一些解决方法。

钱青青
2023-03-14

我不知道这是否仍然与你有关,但我有一个类似的问题。我试着在两个地方都设置了deferred标志:关系类本身和pragma。在这两种情况下,由于OnConflictStrategy,项目都被删除了。替换策略(如您所述,它执行删除操作)。我发现的解决方法是使用类似“UPSERT-like”的查询。去年在SQLite中添加了UPSERT语句支持,所以Room还不支持它,但您可以这样编写:

@Dao
abstract class BaseDao<T> {

    /**
     * Insert an item in the database.
     *
     * @param item the item to be inserted.
     * @return The SQLite row id
     */
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    abstract fun insert(item: T): Long

    /**
     * Insert an array of items in the database.
     *
     * @param items the items to be inserted.
     * @return The SQLite row ids
     */
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    abstract fun insert(items: List<T>): List<Long>

    /**
     * Update an item from the database.
     *
     * @param item the item to be updated
     */
    @Update
    abstract fun update(item: T)

    /**
     * Update an array of items from the database.
     *
     * @param item the item to be updated
     */
    @Update
    abstract fun update(item: List<T>)

    @Transaction
    fun upsert(item: T) {
        val id = insert(item)
        if (id == -1L) {
            update(item)
        }
    }

    @Transaction
    fun upsert(items: List<T>) {
        val insertResult = insert(items)
        val updateList = mutableListOf<T>()

        for (i in insertResult.indices) {
            if (insertResult[i] == -1L) {
                updateList.add(items[i])
            }
        }

        if (updateList.isNotEmpty()) {
            update(updateList)
        }
    }
}

代码背后的逻辑很简单-如果表已经包含记录(这是在插入后通过过滤rowids检查的)-我们应该更新它们。

信用

 类似资料:
  • 问题内容: 如果这是完全相同的内容,请纠正我,我知道这个话题经常被讨论,但是找不到确切的答案。 问题: 在MVC Web应用程序中处理Hibernate对象的最佳实用解决方案是什么? 细节: 我正在使用Hibernate,并希望在可能的情况下利用延迟加载。 我正在使用MVC风格的webapp。 我讨厌获得延迟加载初始化异常。 我讨厌不得不在事务之间重新连接Hibernate对象。 选项: 渴望装载

  • 我一直在寻找能在按键之间有一点延迟的方法。我一直在制作这个程序,它使用JIntellitype库读取全局热键,然后启动您指定的任何一个按键序列,例如按numpad1将执行一个B C序列。我的问题是,如果我使用线程。睡眠它只是延迟X个时间,然后按所有指定的键,在任何按键之间没有任何延迟。有人对如何解决这个问题有什么建议吗?提前谢谢! 这就是我用来发送机器人类按键的东西

  • 本文向大家介绍带宽延迟积,包括了带宽延迟积的使用技巧和注意事项,需要的朋友参考一下 带宽延迟乘积是多少位可以填充网络链路的度量。它给出了发送方在等待确认之前在给定时间可以传输的最大数据量。因此,这是未确认数据的最大数量。 测量 带宽延迟乘积的计算公式是通道的链路容量与传输的往返延迟时间的乘积。 通道的链路容量是每秒传输的位数。因此,其单位为bps,即每秒位数。 往返延迟时间是信号从发送方发送到接收

  • 问题内容: 我正在使用Socket.IO主页(http://socket.io/)中的示例。它可以正常工作,但是在发送数据的时间与从另一端接收到数据之间存在巨大的延迟。 我正在使用XAMPP,我的目录中有socket.html,并在浏览器中使用“ http://localhost/socket.html”导航到它,并且我的服务器在端口8080上侦听。 服务器: HTML档案: 问题答案: 我发现了

  • 问题内容: 我需要在循环中对数据库进行SQL查询: 更好的方法是:保持原样或循环后移动: 或者是其他东西 ? 问题答案: 整个要点是直到函数返回才执行,因此将其放置在要关闭的资源打开后的适当位置。但是,由于要在循环内创建资源,因此根本不要使用defer- 否则,在函数退出之前,您不会关闭在循环内创建的任何资源,因此它们会堆积直到然后。相反,您应该在每次循环迭代结束时关闭它们, 而无需 :

  • 我有一种情况,我的ajax调用必须以特定的顺序执行。我在其他情况下使用了jQueryDeferred对象,但似乎找不到一种方法来使其正常运行。 我有一个函数,在它的生命周期中执行许多请求。一些请求将在其他请求的成功回调期间执行。 我的问题:当调用时,是否有方法将所有嵌套的延迟对象返回到原始的