MyEntity is a classic JPA entity with a generated id. I would like to automatically set a field (myStringField) to a value based on the id. In this example, I’d like to set it to “foo43” if the id is 43.
As id is auto-generated by the DB, it is null before the em.persist(myEntity) call. But after the persist, it has an id assigned by Hibernate (which called NEXTVAL on the DB sequence). So, I though of declaring a @PostPersist method, as follow:
package ...;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PostPersist;
@Entity
public class MyEntity {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String myStringField;
@PostPersist
public void postPersist(){
System.out.println("The id = " + id);
this.myStringField = "foo" + id;
}
public String getMyStringField() {
return myStringField;
}
...
}
Here is some code that creates and persists the entity:
package ...;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class MySpringBean {
@PersistenceContext EntityManager em;
public void createMyEntity() {
MyEntity myEntity = new MyEntity();
em.persist(myEntity);
System.out.println(myEntity.getMyStringField());
}
}
It prints the following output:
The id = 47
foo47
which is fine. But, in the DB, the field myStringField is null ! Does anybody have an idea why?
I did expect the entity would be marked as dirty during the MyEntity.postPersist() method and that an update would occur at the end of the transaction, during the flush. But apprently not.
I use Hibernate v4.2.4
Does someone know why this DB record has a null value?
That's it! I made additional tests and indeed, the @PostPersist is called during the flush (probably because the SQL INSERT is sent during the flush). So, to summarize, things happen in that order: 1. em.persist(), 1.1 NEXTVAL sent to DB and myEntity.id is assigned, 2 end of @Transactional method reached and flush performed. 2.1 INSERT sent to the DB. 2.2 @PostPersist called. 2.2.1 myEntity.myStringField is assigned and entity is dirty. Then no further flush (and dirty checking and update) is performed => no DB save. Many thanks!!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With