【问题标题】:how to swap records having unique constraint in hibernate如何在休眠中交换具有唯一约束的记录
【发布时间】:2014-01-12 16:01:03
【问题描述】:

我有 2 个表用户和用户信息。 userinfo 表包含具有 UNIQUE 约束的 user_id(用户表的 id)列。 现在我有 2 个用户(primaryUser 和 secondaryUser),它们在 user 和 userInfo 表中都有记录。

primaryInfo 对象包含primaryUserId,secondaryInfo 对象包含secondaryUserId

我想将 primaryUser 的 userinfo 数据交换为 secondaryUser,反之亦然。我就是这样的

primaryInfo.setUserId(secondaryUser.getId());                       
secondaryInfo.setUserId(primaryUser.getId());

session.update(primaryInfo);
session.update(secondaryInfo);

但是在提交事务时它会给出错误,例如 错误 org.hibernate.engine.jdbc.spi.SqlExceptionHelper:147 错误:重复键值违反唯一约束“user_infos_unique_user” 详情:密钥 (ui_user_id)=(52560087) 已存在。

你能告诉我怎么做吗..谢谢

【问题讨论】:

    标签: java hibernate postgresql


    【解决方案1】:

    您可以在约束上使用 DEFERRABLE 和 INITIALLY DEFERRED 属性,并在单个事务中更新这两个记录。 DEFERRED 意味着在事务提交之前不会评估约束——此时它应该再次有效。

    但是:我还没有弄清楚如何使用 Hibernate 注释来指定 DEFERRED 属性,因此您将不得不使用 LiquiBase 来维护数据库架构(无论如何这不是一个坏主意。)(或者使用“原始”SQL,即不是一个好主意。)

    See this question for more about the annotations (alas I cannot use LiquiBase on the project I ask about there.)

    【讨论】:

      【解决方案2】:

      对于 Oracle 数据库,您可以使用特殊属性“DEFERRABLE INITIALLY DEFERRED”创建下一个唯一约束:

      ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE (table_field) DEFERRABLE INITIALLY DEFERRED
      

      【讨论】:

        【解决方案3】:

        解决唯一约束的一个可能技巧是进行 3 次更新:

        1. 使用其他行无法使用的列值更新 A 行。 NULL 如果没有被非空约束禁止,则可以使用,否则 0 如果没有被禁止并假设它是一个整数,否则为负值。

        2. 然后用其最终值(A 行的前一个值)更新 B 行

        3. 然后用 A 行的实际最终值(B 行的前一个值)更新 A 行

        【讨论】:

        • 在完成上述过程后遇到同样的问题..这里我使用相同的会话来更新用户信息并在事务提交时收到错误。
        • 如果我在每次会话更新后提交事务,那么它工作正常。但是在所有更新后提交事务,它给出了错误。
        • @user1169474:恐怕这对我来说没有意义。无论何时提交,上述方法都应该有效,因为在 3 个步骤中的任何一个中都不会违反唯一约束。
        • 除上述之外,如果唯一约束在提交时被推迟,那么问题中提到的简单交换方法首先应该没有问题。这正是延迟约束的重点。
        【解决方案4】:

        如错误所示:
        userInfo 表有一个唯一约束。这意味着用户必须是唯一的。所以如果你想刷两个用户ID。您必须执行以下步骤
        1.删​​除约束
        2.交换两个ID(与您当前拥有的代码相同)
        3. 添加约束。

        【讨论】:

        • 报错中显示的id是primaryuserId,我不想去掉Unique约束。
        • 我认为这个解决方案根本不实用。你什么时候打算在真正的应用程序中这样做。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-19
        • 2018-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多