我在插入触发器之前和之后使用在几个表中生成“ID_NAME-000001”形式的id(主键)。目前,这些pojos的hibernate生成器类的值是已分配。随机字符串被分配给要持久化的对象,当它被hibernate插入时,触发器会分配一个正确的id值。
这种方法的问题是我无法检索持久化对象,因为id只存在于数据库中,而不存在于我刚保存的对象中。
我想我需要创建一个可以检索触发器分配的id值的自定义生成器类。我已经看到了oracle(https://forum.hibernate.org/viewtopic.php?f=1&t=973262)的一个例子,但是我无法为MySQL创建类似的东西。有什么想法吗?
谢谢,
更新
似乎这是一个常见且尚未解决的问题。我最终创建了一个新列,作为使用 select 生成器类的唯一键。
答案 0 :(得分: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可以。