如何在使用JPA和Hibernate时选择id生成策略

102 java hibernate jpa uniqueidentifier id-generation

我正在浏览Hibernate参考指南的Id生成部分和"使用Hibernate的java持久性"

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

我正在寻找有关如何选择特定id生成策略的进一步文档.

我也在寻找引爆点.

例如,希望hilo策略可以减少争用.我假设必须有与此选择相关的权衡.

我希望接受有关权衡的教育.

有没有可用的文献?

Man*_*uPK 90

API文档都对这个很清楚.

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

增量

生成long,short或int类型的标识符,仅当没有其他进程将数据插入同一个表时才是唯一的.不要在群集中使用.

身分

支持DB2,MySQL,MS SQL Server,Sybase和HypersonicSQL中的标识列.返回的标识符的类型为long,short或int.

序列

使用DB2,PostgreSQL,Oracle,SAP DB,McKoi中的序列或Interbase中的生成器.返回的标识符的类型为long,short或int

希洛

在给定表和列(分别默认为hibernate_unique_key和next_hi)作为hi值的源的情况下,使用hi/lo算法有效地生成long,short或int类型的标识符.hi/lo算法生成仅对特定数据库唯一的标识符.

seqhilo

在给定命名数据库序列的情况下,使用hi/lo算法有效地生成long,short或int类型的标识符.

UUID

使用128位UUID算法生成在网络中唯一的字符串类型的标识符(使用IP地址).UUID编码为长度为32个十六进制数字的字符串.

GUID

在MS SQL Server和MySQL上使用数据库生成的GUID字符串.

本地人

根据底层数据库的功能选择标识,序列或hilo.

分配

让应用程序在调用save()之前为对象分配标识符.如果未指定任何元素,则这是默认策略.

选择

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

国外

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

序列同一性

一种专门的序列生成策略,它利用数据库序列进行实际值生成,但将其与JDBC3 getGeneratedKeys结合使用,以返回生成的标识符值作为insert语句执行的一部分.仅在针对JDK 1.4的Oracle 10g驱动程序上支持此策略.由于Oracle驱动程序中的错误,对这些插入语句的注释被禁用.

如果你正在构建一个没有多少并发用户的简单应用程序,你可以去增量,身份,hilo等.这些很容易配置,并且在db中不需要太多编码.

您应该根据数据库选择序列guid.这些安全且更好,因为id生成将在数据库内部发生.

更新: 最近我们遇到了一个idendity问题,其中基本类型(int)通过使用warapper类型(整数)来修复.


Vla*_*cea 45

基本上,您有两个主要选择:

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

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

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

  • IDENTITY
  • 序列

当您无法使用SEQUENCE(例如MySQL)时,IDENTITY是一个不错的选择,因为它会禁用JDBC批量更新.

SEQUENCE是首选选项,尤其是与标准优化器(如池化或池化)一起使用时.

应该不惜任何代价避免使用TABLE,因为它使用单独的事务来获取标识符和行级锁定,这些锁定的扩展性很差.


Eya*_*upu 20


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

选择正确的发电机是一项复杂的任务,但重要的是尽快尝试正确 - 后期迁移可能是一场噩梦.

有点偏离主题,但很有可能提出一个点通常被忽视,这是在应用程序之间共享密钥(通过API).我个人总是喜欢代理键,如果我需要与其他系统通信我的对象,我不会暴露我的密钥(即使它是代理密钥) - 我使用额外的"外部密钥".作为一名顾问,我不止一次看过使用对象密钥的"伟大"系统集成("它就是让它只是使用它"的方法)只是为了找到一两年后,一方有关键范围或某事的问题需要在系统上进行深度迁移以暴露其内部密钥的类型.公开您的密钥意味着将代码的基本方面暴露给外部约束不应该真正暴露.