When does the JPA set a @GeneratedValue @Id

Raedwald picture Raedwald · Jan 31, 2012 · Viewed 46.1k times · Source

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
}

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.

The JPA Specification says (emphasis added):

A managed entity instance is an instance with a persistent identity that is currently associated with a persistence context.

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()?

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?

Answer

Thomas picture Thomas · Jan 31, 2012

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.

Thomas

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.