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!