问题描述
我有一个简单的 JPA 实体,它使用生成的 long
ID"作为其主键:
I have a simple JPA entity that uses a generated long
"ID" as its primary key:
@Entity
public class Player {
private long id;
protected Player() {
// Do nothing; id defaults to 0L
}
@GeneratedValue
@Id
public long getId() {
return id;
}
protected void setId(final long id) {
this.id = id;
}
// Other code
}
在这种类型的对象生命周期的某个时刻,JPA 必须调用 setId()
来记录生成的 ID 值.我的问题是,什么时候会发生这种情况,说明这一点的文档在哪里.我已经查看了 JPA 规范,但找不到明确的声明.
At some point in the life-cycle of an object of this type the JPA must call setId()
to record the generated ID value. My question is, when does this happen, and where is the documentation that states this. I've looked through the JPA Specification and can not find a clear statement.
JPA 规范说(强调):
The JPA Specification says (emphasis added):
托管实体实例是具有当前与持久性上下文关联的持久身份的实例.
这是说对象必须被管理以使其@Id
有意义吗?EntityManager.persist()
的文档说(强调)它使一个实例管理和持久化",这是否意味着 @Id代码> 是由该方法设置的?还是直到你调用
EntityTransaction.commit()
?
Is that trying to say that the the object must be managed to have its @Id
significant?The documentation for EntityManager.persist()
says (emphasis added) it makes "an instance managed and persistent", so does that mean that the @Id
is set by that method? Or is it not until you call EntityTransaction.commit()
?
@Id
的设置时间对于不同的 JPA 提供程序可能会有所不同,并且可能对于不同的生成策略.但是,对于生命周期中已设置的最早点,您可以做出的最安全(便携、符合规范)的假设是什么?
When the @Id
is set might be different for different JPA providers, and perhaps for different generation strategies. But what is the safest (portable, specification conforming) assumption that you can make about the earliest point in the lifecycle that it has been set?
推荐答案
调用 .persist() 不会自动设置 id 值.您的 JPA 提供程序将确保在实体最终写入 db 之前设置它.因此,您可以假设在提交事务时分配 id 是正确的.但这并不是唯一可能的情况.当你调用 .flush() 时,同样会发生.
calling .persist() will not automatically set the id value. Your JPA provider will ensure that it is set before the entity is finally written to db. So you are right to assume that the id will be assigned when the transaction is committed. But this is not the only possible case. When you call .flush() the very same will happen.
托马斯
更新:请注意 Geek 的评论.-> 如果使用 GenerationType.Identity,则在实体写入 db 之前提供者不会设置 id.在这种情况下,id 生成发生在 db 级别的插入过程中.无论如何,JPA 提供者将确保实体随后更新,并且生成的 id 将在 @Id 注释属性中可用.
Update: Pay attention to Geek's comment, please. -> If GenerationType.Identity is used, the id will not be set by the provider before the entity is written to db. In this case id generation happens during the insert process on db level. Anyway, the JPA provider will ensure that the entity is updated afterwards and the generated id will be available in the @Id annotated property.
这篇关于JPA 何时设置 @GeneratedValue @Id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!