繁体   English   中英

jpa序列ID生成

[英]jpa sequence ID generation

通过在将实体持久保存到数据库之前将ID分配给实体来获得巨大的价值,但是在构造函数中立即执行:您的equals / hashcode实现变得微不足道, 并且它可以节省许多麻烦

当实体等式基于==时,我已经看到了问题:代理进入会话,当它作为真实对象被解包时,你得到返回false equals()

当你重写equalshashcode以使用生成的ID时,因为那个只在persist()上生成,所有非持久化实体都具有id null ,因此它们彼此相等。

从我读到的内容来看,当你使用传统的ID生成技术时(比如说自动增量),在刷新实体管理器时会生成ID。 当您使用基于序列的解决方案时,它会在持续时间生成。

那篇文章和我目前的理解说最简单的解决方案是在创建时分配ID,而不是持久或刷新时间。 并且序列似乎可以到达,但JPA决定反对它。 通过序列获取ID是便宜的(因为你可以预取),为什么JPA至少没有提供在对象构建时获得基于序列的ID的选项? 如果实体最终没有持久存在,则存在浪费一些ID的风险,但我认为这不是一个大问题。

除此之外,就解决方案的简单性和可理解性而言,唯一的“不妥协”似乎是UUID,它们都有自己的问题。

我错过了什么吗? 是否有某些JPA身份生成器或某些库将基于序列并允许在构建时提供ID?

从写作的角度来看,使用指定的标识符是最好的方法。 它在所有实体状态转换中也是一致的,您甚至可以在JDBC级别批量多个插入。

在阅读和索引方面,数字列表现更好,分配的标识符是唯一的逻辑密钥(社会安全号码)或唯一标识符(例如UUID)。 使用应用程序级唯一分配的标识符很复杂,因为您可能有多个应用程序节点(在群集中),或者您希望在应用程序内部以及从外部源(数据库客户端实用程序)同步插入。

对于数据库分配的标识符,您需要考虑如何根据您的选择影响刷新。 Hibernate试图将持久性上下文推迟到最后一刻 这种策略传统上称为事务性后写。

后写与Hibernate刷新更相关,而不是任何逻辑或物理事务。 在交易期间,可以多次发生冲洗。

刷新的更改仅对当前数据库事务可见。 在提交当前事务之前,其他并发事务不会看到任何更改。

IDENTITY需要刷新 ,而序列是非事务性的,因此它不需要刷新。 IDENTITY禁用JDBC插入批处理,它不支持预分配。

JPA无法在Entity构造时分配标识符,因为新实例只能通过EntityManager.persist()调用保持持久化。 JPA需要明确的“实体状态转换”。

浪费序列标识符不是什么大问题。 即使序列值存在间隙,数据库也能正常运行。 使用bigint列可以保证您实际上不会用尽序列标识符。 具有偶然间隙的非事务性序列标识符分配比具有较高死锁争用风险的事务分配更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM