I am currently working with @PostPersist
and @PostUpdate
, and in those triggers I am persisting additional entities. The question is, are those triggers in the same transaction and if not is it possible to force it ?
For me it works this way.
While I was looking through the logs the transaction isn't existing ( it's commited just before the trigger is launched ) which prevents me ( without REQUIRES_NEW
on the persisting method from injected bean ) from saving the additional entities in database.
REQUIRED
attribute is totally ignored, and MANDATORY
attribute do not throw an exception.
Can it be the problem with JUnit ( since I am in the dev. phase and did not test the behavior on full env. ) ?
If extending the transaction on this triggers is not possible, how to ensure that if the rollback occurs before the @PostPersist
and @PostUpdate
, those operations also will be rollbacked.
JPA's 4 Lifecycle States. The lifecycle model consists of the 4 states transient, managed, removed, and detached.
JPA specifies seven optional lifecycle events that are called: before persist is called for a new entity – @PrePersist. after persist is called for a new entity – @PostPersist. before an entity is removed – @PreRemove. after an entity has been deleted – @PostRemove.
The @PrePersist annotation is used to configure a callback for pre-persist(pre-insert) events of the entity. In other words, it is used to annotate model methods to indicate that the method should be called before the entity is inserted (persisted) into the database.
JPA includes a variety of callbacks methods for monitoring changes in the lifecycle of your persistent objects. These callbacks can be defined on the persistent classes themselves and on non-persistent listener classes.
If you're using Spring you could always register a TransactionSynchronization
with your current transaction manager to be called back on events such as commits of your currently running transaction:
@PostPersist
void onPersist() {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void beforeCommit(boolean readOnly) {
// do work
}
});
}
}
A TransactionSynchronization
also provides callbacks after a transaction has committed successfully and before/after a transaction completes.
If you need to inspect if the transaction was committed or rolled back, use afterCompletion(int status)
.
For details have a look at TransactionSynchronization's JavaDoc.
The firing of a PostPersist event does not indicate that the entity has done a successful commit. The transaction may be rolled back after the firing of the event but before the successful commit. If you in the PostPersist get the entity manager used in the transaction and then do somehting like this:
@PostPersist
void someMethod() {
EntityManager em = null;
em = getEntityManagerUsedInTransaction();
EntityTransaction et = em.getTransaction(); // should return the current transaction
if (et.isActive() ) {
// do more db stuff
}
}
NB: I haven't tried this so it's only speculation (tho' I have used the lifetime event trigger extensively for other stuff). I have to add that I don't think this is a good idea. Use the PostPersist to flag that other entities should be persisted and do it in another transaction.
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