Hibernate如何填充自动生成字段的ID?

7

假设我有一个带有自动生成主键的实体。现在,如果我尝试保存该实体与所有其他字段的值,这些值可能不是唯一的。 该实体将自动填充插入行的id。它是如何获得该主键值的?

编辑:

如果主键列是标识列,其值完全由数据库决定,则它将执行不带该列值的插入语句,并由数据库决定要使用的值,但它没有回传这个决定(我认为不会)。

3个回答

7
Hibernate使用三种方法来提取数据库自动生成的字段,具体取决于JDBC驱动程序或您使用的方言支持什么。
Hibernate将生成的字段值提取出来并放回到POJO中:
1. 使用Statement.getGeneratedKeys方法(Statement javadocs)。 或者 2. 直接从插入语句中插入并选择生成的字段值。 (Dialect Javadocs) 或者 3. 在插入后执行select语句以检索生成的IDENTITY值。
所有这些都是由Hibernate在内部完成的。
希望这是您要找的解释。

完美。正是我在寻找的,谢谢。但是我没有真正理解第三点。如何使用select语句获取标识值?鉴于行值除了生成的值之外并不唯一。 - vinothkr
1
这是一个特定于你所使用的方言的函数。选择不是基于域对象中字段的组合。在Mysql中,它使用"SELECT LAST_INSERT_ID()"(参见[链接](http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html))。 - Joel Hudon

1

这个Hibernate文档部分描述了自动生成ID的过程。通常情况下,使用AUTO生成策略可以实现最大的可移植性,并且假设您使用注释来提供您的域元数据,您可以按照以下方式进行配置:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;

无论如何,提供的链接应该为您提供有关生成ID所需的所有详细信息。


不错,但我的问题是假设它是一个标识列,其下一个值完全由DB决定,那么Hibernate如何知道它更新的行具有主键值x。我编辑了我的问题。 - vinothkr
我不确定你的意思,但标识符的值将被传回,因为它将设置在您插入的域实例上。 - Alex Barnes
1
此外,数据库用于ID的值取决于数据库类型。Oracle将使用SEQUENCE,MySQL将使用自动递增值等。 - Alex Barnes

0

当您使用序列派生的代理主键创建对象时,将该字段设置为Hibernate默认解释为“未分配”的值(默认为0),并将其传递给Hibernate会话。在相应的记录未插入到数据库表中之前,此字段不会填充已分配的值。您可以通过在Hibernate会话上显式调用flush()或在同一会话中执行数据库读取来触发插入。之后,您可以检查该字段的值,它将被分配而不是0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接