5

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?

4

5 に答える 5

0

使用する

@PrePersist

代わりに、メソッドフィールドの生成は私にとって正しくありません.myStringFieldがjpa IDとは異なるビジネスIDになる場合は、Beanの初期化時に作成されると想定する必要があります。

ビジネス ID の扱い方の例については、equals()/hashcode() ジレンマに関するこのスレッドと、特にこの応答を参照することをお勧めします: https://stackoverflow.com/a/5103360/2598693

于 2013-08-21T07:41:55.543 に答える
0

POST 永続化を行っているため、データベースへの書き込み後に発生します。

JPA @PostPersist の使用に対する回答によると、仕様は次のように述べています

These database operations may occur directly after the persist, merge, or remove operations have been invoked or they may occur directly after a flush operation has occurred

于 2013-08-20T15:09:40.703 に答える