首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JPA何时设置@GeneratedValue @Id?

JPA何时设置@GeneratedValue @Id?
EN

Stack Overflow用户
提问于 2012-01-31 22:18:08
回答 4查看 49.4K关注 0票数 50

我有一个简单的JPA实体,它使用生成的long "ID“作为主键:

代码语言:javascript
复制
@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规范,找不到明确的声明。

JPA规范规定(强调后加):

托管实体实例是一个具有持久标识的实例,该实例当前与持久性上下文相关联。

这是否意味着必须对对象进行管理以使其@Id具有重要意义?EntityManager.persist()的文档说(强调后加)它使“一个实例被管理和持久”,那么这是否意味着@Id是由该方法设置的?或者是在你打电话给EntityTransaction.commit()之前

当设置@Id时,对于不同的JPA提供者,或者对于不同的生成策略,可能是不同的。但是,什么是最安全的(可移植的,符合规范的)假设,您可以提出关于生命周期中已经设置的最早点的假设?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-31 22:43:11

调用.persist()不会自动设置id值。您的JPA提供程序将确保在实体最终写入db之前设置它。因此,您正确地假设,在提交事务时将分配id。但这不是唯一可能发生的情况。当您调用.flush()时,同样的情况也会发生。

托马斯

更新:请注意极客的评论。->如果使用GenerationType.Identity,则在将实体写入数据库之前,该提供程序将不会设置id。在这种情况下,id生成发生在db级别的插入过程中。无论如何,JPA提供程序将确保实体在更新之后被更新,生成的id将在@Id注释属性中可用。

票数 25
EN

Stack Overflow用户

发布于 2012-01-31 22:47:40

AFAIK,只有在刷新持久性上下文时才能保证分配ID。它可能会更早地被分配,但它取决于生成策略。

票数 12
EN

Stack Overflow用户

发布于 2012-02-26 13:24:00

“企业”( Enterprise JavaBeans 3.1,Rubinger和Burke )一书在第143页(重点后加)写道:

Java还可以配置为在通过在主键字段或setter上使用persist()注释调用方法时自动生成主键。因此,在前面的示例中,如果启用了自动密钥生成,则可以在persist()方法完成后查看生成的密钥。

JPA规范规定(强调后加):

托管实体实例是一个具有持久标识的实例,该实例当前与持久性上下文相关联。

也是EntityManager.persist()制造的

管理和持久的实例

由于@Id对于实体的标识至关重要,所以EntityManager.persist()使对象管理的唯一方法是通过生成@Id来建立其标识。

然而,

Rubinger和Buke的明确声明与Hibernate的行为不一致。因此,似乎知识渊博的人对JPA规范的意图有争议。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9087848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档