tags:

views:

43

answers:

1

I'm trying to connect an external application to a JBoss AS container. The external application is a Java application that is currently being notified of changes to database entities through a JMS topic. I've added an EntityLifecycleListener class to all my entities that publishes a serialized (and unwrapped) copy of the entity to the JMS topic.

The problem is that this implementation ignores the transaction boundaries of the JBoss container. For example, the @PostUpdate event can be fire, generating the JMS message for that entity, but the transaction could be rolled back causing the external application to be notified of an invalid change and become unsync'd.

I need my external application to only be notified of successful commits to the database, but I need to be able to publish the entire java POJO to the external application. Is there an official way of doing this?

+1  A: 

The JPA spec are a bit vague about transaction demarcation and the listener (§ 3.5.2):

The PreUpdate and PostUpdate callbacks occur before and after the database update operations to entity data respectively.

I had a similar situation, and so far I remember, the callback @PostXxxx were sometimes executed in the correct transaction or no transaction at all. That depends whether the update was an "intermediate" flush in the transaction or the "last" flush before the transaction is committed, in which case the callback happens after the transaction was committed (which makes sense).

I suggest you try with @PreXxxxx which should always be in the transaction. (Also, if I remember well, the only problem with @PreXxxx was that the entity may not be assigned a PK yet, whether it's problematic depends on your use case.)

ewernli
By using the @PreXxxx wouldn't I be publishing stale data since it would occur before the entity is updated?If the transaction is rolled back wouldn't I have the same issue? This is a specific case that I see:I call a Session Bean method; the bean loads an entity from the database, makes some change changes and then performs an EntityManager.flush(). This cause the Persistent Context to sync which fires the callback listeners. The next line in the bean throws an exception. This cause the transaction to rollback and the data to not commit. But I've still published my JMS message.
John Engelman
@John Not if you use distributed transactions. The flush sync the data and fires the callback. The message is sent, but belongs to the *distributed* transaction. If the tx fails later, nothing is committed (db + jms).
ewernli