休眠触发器生成的ID(MySQL)问题
我在插入触发器之前和之后使用几个表中的“ID_NAME-000001”形式生成ID(主键)。目前,这些pojos的hibernate generator类的值是,分配为。一个随机字符串被分配给要被持久化的对象,当它被hibernate插入时,触发器会分配一个正确的id值。休眠触发器生成的ID(MySQL)问题
这种方法的问题是我无法检索持久对象,因为该ID只存在于数据库中,而不存在于我刚刚保存的对象中。
我想我需要创建一个自定义生成器类,可以检索由触发器分配的id值。我已经看到了一个用于oracle的例子(https://forum.hibernate.org/viewtopic.php?f=1&t=973262),但我还没有能够为MySQL创建类似的东西。有任何想法吗?
感谢,
更新:
看来,这是一种常见的,但是,没有解决问题。我最终创建了一个新列,作为使用选择生成器类的唯一键。
希望这不会引发神圣的战争是否使用代用钥匙。但现在是时候在这里打开对话。
另一种方法是,使用生成的密钥作为代理键并为触发器分配的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)时,我发现在选择主键时出现错误。不幸的是,在这个阶段无法纠正这个问题。 – greatgoron 2011-02-26 06:55:28
是的,我同意。当您仍处于设计阶段时,更换容易。当您的应用程序处于制作和支持状态时,可能需要花费很大力气才能更改密钥。 – 2011-02-28 04:12:53