Hi Mark,

I think you're asking a different question, which I'll try to posit here:

What happens in this sequence?

    Person p;
    tran.begin();
    em.persist(p);
em.flush();

    p.setName("Mike");
    tran.commit();

Does the extra flush cause any new callbacks? And when, exactly, is @PrePersist called?

I'd expect that the flush changes things. The @PrePersist must be called before the database insert operation. But note that the behavior of a subsequent set/commit is not completely standardized in the JPA specification:

JSR-317 Final Release 95   11/10/09

The PrePersist and PreRemove callback methods are invoked for a given entity before the respective EntityManager persist and remove operations for that entity are executed. For entities to which the merge operation has been applied and causes the creation of newly managed instances, the PrePersist callback methods will be invoked for the managed instance after the entity state has been copied to it. These PrePersist and PreRemove callbacks will also be invoked on all entities to which these operations are cascaded. The PrePersist and PreRemove methods will always be invoked as part of the synchronous persist, merge, and remove operations.

The PostPersist and PostRemove callback methods are invoked for an entity after the entity has been made persistent or removed. These callbacks will also be invoked on all entities to which these operations are cascaded. The PostPersist and PostRemove methods will be invoked after the database insert and delete operations respectively. 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 (which may be at the end of the transaction). Generated primary key values are
available in the PostPersist method.

The PreUpdate and PostUpdate callbacks occur before and after the database update operations to entity data respectively. These database operations may occur at the time the entity state is updated or they may occur at the time state is flushed to the database (which may be at the end of the transaction).

Note that it is implementation-dependent as to whether PreUpdate and PostUpdate call- backs occur when an entity is persisted and subsequently modified in a single transaction or when an entity is modified and subsequently removed within a single transaction. Portable
applications should not rely on such behavior.

Regards,

Craig

On Feb 9, 2011, at 10:34 AM, Mark Struberg wrote:

Yes, but the question is _when_ do we get the PrePersist?

Does the em.persist always write to the database, or only if a database managed id sequence gets used?

In this case, I'd say we have a blind spot, because a subsequent change and flush of those changes will create a subsequent update which isn't covered by a @PreUpdate.

But if the effective storage (and the @PrePersist) only gets called at tran.commit() then all is fine.

LieGrue,
strub

--- On Wed, 2/9/11, Michael Dick <[email protected]> wrote:

From: Michael Dick <[email protected]>
Subject: Re: Does PrePersist work when merging entities? (2.0.1)
To: [email protected]
Date: Wednesday, February 9, 2011, 5:30 PM
Here's my take :

In OpenJPA 1.x if you did something like this :

    Person p;
    tran.begin();
    em.persist(p);

    p.setName("Mike");
    tran.commit();

You would get a PrePersist, and a PreUpdate and PostUpdate
callback. In
OpenJPA 1.3, and version 2.x you'll only get the PrePersist
one.

-mike

On Wed, Feb 9, 2011 at 9:23 AM, Joel Halbert <[email protected]>
wrote:

What's the significance of this, from the docs?

"If an entity was updated between the persist() and
commit() operations
in OpenJPA 1.x, then any PreUpdate and PostUpdate life
cycle callback
methods would be executed. Starting in OpenJPA 1.3 and
2.0, these
callbacks will not get executed."

http://openjpa.apache.org/builds/2.0.1/apache-openjpa-2.0.1/docs/manual/main.html

Does it mean we should not rely on PreUpdate?



On Wed, 2011-02-09 at 15:16 +0000, Joel Halbert
wrote:
Doh!!! Thanks for clarifying.

On Wed, 2011-02-09 at 15:13 +0000, Mark Struberg
wrote:
Hi Joel!

You might look at @PreUpdate.

@PrePersist only gets called before a
em.persist() performs the sql
INSERT statement. @PreUpdate will get called before
any sql UPDATE to the
entity.

LieGrue,
strub

--- On Wed, 2/9/11, Joel Halbert <[email protected]>
wrote:

From: Joel Halbert <[email protected]>
Subject: Does PrePersist work when
merging entities? (2.0.1)
To: "[email protected]"
<[email protected]>
Date: Wednesday, February 9, 2011, 3:06
PM
Hi Folks,

Are there any known issues around
using  @PrePersist
on merge with
2.0,.1?
My Entities use Property access.

@PostLoad method is always called when
loading entities.
@PrePersist is called on persist, but
never on merge.

I'm tried using both runtime (agent)
and compile time
enhancement.

Here's a sample Entity that I used for
testing this.



import javax.persistence.*;

@Entity
@Access(AccessType.PROPERTY)
@Table(name="TEST")
public class Test {

     private int
id;
     private String
name;

     @Id

   @GeneratedValue(strategy =
GenerationType.IDENTITY)

   @Column(name="ID")
     public int
getId() {

   return id;
     }
     public void
setId(int id) {

   this.id = id;
     }


   @Column(name="NAME")
     public String
getName() {

   return name;
     }
     public void
setName(String name) {

   this.name = name;
     }

     @PrePersist
     void
populateDBFields(){

System.out.println("Hello, I happen
prePersist!");
     }

     @PostLoad
     void
populateTransientFields(){

System.out.println("Hello, I happen
postLoad!");
     }

     public static
void main(String[] args)
throws Exception {

   EntityManagerFactory
factory =
Persistence.createEntityManagerFactory(

     "su3", null);

   EntityManager em =
factory.createEntityManager();


   // Test t = new
Test();

   //
t.setName("name");

   // em.persist(t);


   Test t =
em.find(Test.class, 1);

   t.setName("new
name");

   em.merge(t);


em.getTransaction().commit();

   em.close();

     }
}




Any clues?

Joel






____________________________________________________________________________________
8:00? 8:25? 8:40? Find a flick in no time
with the Yahoo! Search movie showtime
shortcut.
http://tools.search.yahoo.com/shortcuts/#news










Craig L Russell
Architect, Oracle
http://db.apache.org/jdo
408 276-5638 mailto:[email protected]
P.S. A good JDO? O, Gasp!

Reply via email to