带有 GenerationType.IDENTITY 的 JPA 和 PostgreSQL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40497768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 02:26:19  来源:igfitidea点击:

JPA and PostgreSQL with GenerationType.IDENTITY

postgresqlhibernatejpa

提问by Mike

I have a question about Postgres and GenerationType.Identity vs Sequence

我有一个关于 Postgres 和 GenerationType.Identity vs Sequence 的问题

In this example...

在这个例子中...

@Id
@SequenceGenerator(name="mytable_id_seq",
                   sequenceName="mytable_id_seq",
                   allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
                generator="mytable_id_seq")

I understand that I am specifying a Postgres sequence to use via annotations.

我知道我正在指定要通过注释使用的 Postgres 序列。

However, I have an id column defined with the 'serial' type, I have read that I can simply use GenerationType.IDENTITY and it will automatically generate a db sequence and use it to auto increment.

但是,我有一个用“串行”类型定义的 id 列,我读到我可以简单地使用 GenerationType.IDENTITY,它会自动生成一个 db 序列并使用它来自动递增。

If that's the case, I don't see an advantage to using the SEQUENCE annotations unless you are using an integer for an id or have some specific reason to use another sequence you have created. IDENTITY is alot less code and potentially makes it portable across databases.

如果是这种情况,我认为使用 SEQUENCE 注释没有优势,除非您使用整数作为 id 或有某些特定原因使用您创建的另一个序列。IDENTITY 代码少很多,并且有可能使其跨数据库移植。

Is there something I'm missing?

有什么我想念的吗?

Thanks in advance for the feedback.

提前感谢您的反馈。

回答by Glenn

If you have a column of type SERIAL, it will be sufficient to annotate your idfield with:

如果您有一列 type SERIAL,则id用以下内容注释您的字段就足够了:

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)

This is telling Hibernate that the database will be looking after the generation of the idcolumn. How the database implements the auto-generation is vendor specific and can be considered "transparent" to Hibernate. Hibernate just needs to know that after the row is inserted, there will be an idvalue for that row that it can retrieve somehow.

这告诉 Hibernate 数据库将负责id列的生成。数据库如何实现自动生成是特定于供应商的,可以认为对 Hibernate 是“透明的”。Hibernate 只需要知道在插入行后,该行会有一个id值,它可以以某种方式检索。

If using GenerationType.SEQUENCE, you are telling Hibernate that the database is not automatically populating the idcolumn. Instead, it is Hibernate's responsibility to get the next sequence value from the specified sequence and use that as the idvalue when inserting the row. So Hibernate is generating and inserting the id.

如果使用GenerationType.SEQUENCE,您是在告诉 Hibernate 数据库不会自动填充该id列。相反,Hibernate 有责任从指定的序列中获取下一个序列值,并将其用作id插入行时的值。因此 Hibernate 正在生成并插入id.

In the case of Postgres, it happens that defining a SERIALcolumn is implemented by creating a sequence and using it as a default column value. But it is the database that is populating the idfield so using GenerationType.IDENTITYtells Hibernate that the database is handling id generation.

在 Postgres 的情况下,碰巧SERIAL通过创建序列并将其用作默认列值来实现定义列。但是填充该id字段的是数据库,因此 usingGenerationType.IDENTITY告诉 Hibernate 数据库正在处理 id 生成。

These references may help:

这些参考资料可能有帮助:

http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators

http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators

https://www.postgresql.org/docs/8.1/static/datatype.html#DATATYPE-SERIAL

https://www.postgresql.org/docs/8.1/static/datatype.html#DATATYPE-SERIAL

回答by Nikola

From "Pro JPA2" book:

来自“ Pro JPA2”一书:

"Another difference, hinted at earlier, between using IDENTITY and other id generation strategies is that the identifier will not be accessible until after the insert has occurred. Although no guarantee is made about the accessibility of the identifier before the transaction has completed, it is at least possible for other types of generation to eagerly allocate the identifier. But when using identity, it is the action of inserting that causes the identifier to be generated. It would be impossible for the identifier to be available before the entity is inserted into the database, and because insertion of entities is most often deferred until commit time, the identifier would not be available until after the transaction has been committed."

“前面暗示过,使用 IDENTITY 和其他 id 生成策略之间的另一个区别是,在插入发生之前,标识符将无法访问。虽然不能保证事务完成之前标识符的可访问性,但它是至少其他类型的生成可能会急切地分配标识符。但是在使用身份时,正是插入的动作导致了标识符的生成。在将实体插入到实体之前,标识符是不可能可用的数据库,并且因为实体的插入通常推迟到提交时间,所以标识符在事务提交之后才可用。”

回答by osama yaccoub

I think it can be helpful if you are using the same sequence for more than one table (for example you want a unique identifier for many types of bills) ... also If you want to keep track of the sequence away from the auto generated key

我认为如果您对多个表使用相同的序列(例如,您想要多种类型的账单的唯一标识符),这可能会有所帮助......此外,如果您想跟踪自动生成的序列钥匙