【问题标题】:Problem with hibernate trigger-generated ids (MySQL)休眠触发器生成的ID问题(MySQL)
【发布时间】:2011-02-23 21:14:10
【问题描述】:

我使用前后插入触发器在多个表中生成“ID_NAME-000001”形式的 ID(主键)。目前,这些 pojo 的休眠生成器类的值是赋值。一个随机字符串被分配给要持久化的对象,当它被休眠插入时,触发器会分配一个正确的 id 值。

这种方法的问题是我无法检索持久化的对象,因为 id 只存在于数据库中,而不存在于我刚刚保存的对象中。

我想我需要创建一个自定义生成器类,它可以检索触发器分配的 id 值。我已经看到了 oracle (https://forum.hibernate.org/viewtopic.php?f=1&t=973262) 的一个示例,但我无法为 MySQL 创建类似的东西。有什么想法吗?

谢谢,

更新:

似乎这是一个常见但尚未解决的问题。我最终创建了一个新列作为使用 select 生成器类的唯一键。

【问题讨论】:

    标签: mysql hibernate triggers generator


    【解决方案1】:

    希望这不会引发一场关于是否使用代理键的圣战。但现在是时候在这里开启对话了。

    另一种方法是,使用生成的键作为代理键并为您的触发器分配的 ID 分配一个新字段。代理键是主键。您有逻辑命名的键(例如您的示例中的“ID_NAME-000001”)。因此,您的数据库行将有 2 个键,主键是代理键(可以是 UUID、GUID、运行号)。 通常这种方法更可取,因为它可以更好地适应新的变化。 比如说,你有这些行使用代理键而不是使用生成的 id 作为自然键。

    代理键:

    id: "2FE6E772-CDD7-4ACD-9506-04670D57AA7F", logical_id: "ID_NAME-000001", ...
    

    自然键:

    id: "ID_NAME-000001", ...
    

    当以后一个新的需求需要logical_id 是可编辑的、可审计的(它是否被更改、谁在何时更改)或可转移时,将logical_id 作为主键会给您带来麻烦。通常你不能改变你的主键。当您的数据库中已经有大量数据并且由于新要求而必须迁移数据时,这是非常不利的。

    使用代理键解决方案,很简单,你只需要添加

    id: "2FE6E772-CDD7-4ACD-9506-04670D57AA7F", logical_id: "ID_NAME-000001", valid: "F", ...
    id: "0A33BF97-666A-494C-B37D-A3CE86D0A047", logical_id: "ID_NAME-000001", valid: "T", ...
    

    MySQL 不支持序列(IMO 自动增量无法与序列相比较)。它与 Oracle/PostgreSQL 的顺序不同。我想这就是为什么很难将解决方案从 Oracle 数据库移植到 MySQL 的原因。 PostgeSQL 可以。

    【讨论】:

    • 感谢您的推荐。在我添加新列(自定义 UUID)的那一刻,我意识到选择主键时的错误。不幸的是,现阶段无法纠正。
    • 是的,我同意。当您仍处于设计阶段时,更改会容易得多。当您的应用处于生产和支持阶段时,可能需要花费大量精力来更改密钥。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多