如何在使用JPA和Hibernate时selectid生成策略

我正在通过Hibernate参考指南的Id生成部分和“与Hibernate的Java持久性”

Hibernate和JPA结合使用的选项有很多。

我正在寻找关于如何select特定的id生成策略的进一步的文档。

我也在寻找引爆点。

例如,hilo策略有望减less争用。 我假设必须有一个与这个select相关的折衷。

我想受到关于权衡的教育。

有没有任何文献可用?

API Doc对此非常清楚。

所有的生成器都实现了org.hibernate.id.IdentifierGenerator接口。 这是一个非常简单的界面。 有些应用程序可以select提供自己的专用实现,但是,Hibernate提供了一系列的内置实现。 内置生成器的快捷方式名称如下所示:

增量

生成long,short或inttypes的唯一标识符,只有在没有其他进程将数据插入到同一个表中时才是唯一的。 不要在群集中使用。

身分

支持DB2,MySQL,MS SQL Server,Sybase和HypersonicSQL中的标识列。 返回的标识符的types是long,short或int。

序列

在Interbase中使用DB2,PostgreSQL,Oracle,SAP DB,McKoi或生成器中的序列。 返回的标识符的types是long,short或int

希洛

使用hi / loalgorithm来高效地生成long,short或inttypes的标识符,给定一个表和列(分别默认为hibernate_unique_key和next_hi)作为hi值的来源。 hi / loalgorithm生成仅对特定数据库唯一的标识符。

seqhilo

给定一个命名的数据库序列,使用hi / loalgorithm高效地生成long,short或inttypes的标识符。

UUID

使用128位的UUIDalgorithm来生成networking中唯一的stringtypes(使用IP地址)的标识符。 UUID被编码为长度为32个hex数字的string。

GUID

在MS SQL Server和MySQL上使用数据库生成的GUIDstring。

本地人

根据底层数据库的functionselect身份,序列或hilo。

分配

让应用程序在调用save()之前为对象分配一个标识符。 如果没有指定元素,这是默认策略。

select

检索由数据库触发器分配的主键,方法是通过某个唯一键select该行并检索主键值。

国外

使用另一个关联对象的标识符。 它通常与主键联合使用。

序列同一性

一个专门的序列生成策略,它利用数据库序列来生成实际的值,但将其与JDBC3 getGeneratedKeys结合,以返回生成的标识符值作为插入语句执行的一部分。 只有针对JDK 1.4的Oracle 10g驱动程序才支持此策略。 由于Oracle驱动程序中的错误,对这些插入语句的评论被禁用。

如果你正在构build一个简单的应用程序,并没有太多的并发用户,你可以去增加,身份,HILO等等。这些configuration很简单,并不需要太多的编码在数据库中。

你应该select序列GUID取决于你的数据库。 这些都是安全的,更好的,因为id生成将发生在数据库内部。

更新: 最近我们遇到了一个问题,原始types(int)通过使用warappertypes(Integer)来解决。

基本上,你有两个主要的select:

  • 您可以自己生成标识符,在这种情况下,您可以使用分配的标识符 。
  • 您可以使用@GeneratedValue注释,Hibernate将为您分配标识符。

对于生成的标识符,您有两个select:

  • UUID标识符 。
  • 数字标识符。

对于数字标识符, 您有三个选项 :

  • IDENTITY
  • 序列

当你不能使用SEQUENCE(例如MySQL)时,IDENTITY只是一个不错的select,因为它会禁用JDBC批量更新 。

SEQUENCE是首选选项,特别是在与标准优化器(如池化池或池化池)一起使用时。

TABLE可以避免任何代价,因为它使用一个单独的事务来获取尺度较差的标识符和行级锁。

前一段时间,我写了一篇关于Hibernate密钥生成器的详细文章: http : //blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

select正确的发生器是一项复杂的任务,但重要的是要尽快把它做好,迟到的迁移可能是一场噩梦。

一个小题目,但提出一个很好的机会通常被忽视的是应用程序之间共享密钥(通过API)。 就个人而言,我总是喜欢代理键,如果我需要与其他系统沟通我的对象,我不会暴露我的密钥(即使它是一个代理键) – 我使用一个额外的“外部键”。 作为一名顾问,我不止一次看到使用对象密钥的“伟大的”系统集成(“它就在那里让我们使用它”的方法),只是在一两年后发现一方有关键范围问题或者这种types需要在系统上进行深度迁移,暴露其内部密钥。 暴露你的密钥意味着暴露你的代码的一个基本方面外部约束不应该真正暴露。

我觉得这个讲座非常有价值https://vimeo.com/190275665 ,第三点总结了这些生成器,并给出了一些性能分析和指导原则之一。