6 Replies Latest reply on Jul 15, 2006 12:27 PM by jnorris10

    Entity bean state not rolled back on TX rollback:

    jnorris10

      I have an entity bean with a "id" property annotated by:

      @Id
      @GeneratedValue
      


      However, when this transaction fails with a database level deadlock and is rolled back (ie: EJBTransactionRolledbackException ...), the entity's "id" property is not rolled back and still has the database generated id value that it was given before the deadlock. So it essentially becomes a detached entity with no real backing value in the database.

      Shouldn't an entity bean's state be rolled back as well when the application TX is rolled back? Is this a bug?

      The rollback is initiated by a database deadlock and is described by the following exception stack:

      javax.ejb.EJBTransactionRolledbackException
      javax.persistence.PersistenceException
      org.hibernate.exception.LockAcquisitionException: could not insert: ...
      java.sql.SQLException: Deadlock found when trying to get lock; try restarting transaction
      


      Let me know if you need more information to reproduce/investigate this...

      Thanks.


        • 1. Re: Entity bean state not rolled back on TX rollback:
          jnorris10

          Sorry... I am running JBoss 4.0.4.GA (w/ EJB3 RC7)

          • 2. Re: Entity bean state not rolled back on TX rollback:
            jnorris10

            Also, I am using CMT (container managed transactions)

            • 3. Re: Entity bean state not rolled back on TX rollback:
              bill.burke

              we could possible put this in, but it would not be portable behavior. The spec doesn't require rollback of entity state.

              • 4. Re: Entity bean state not rolled back on TX rollback:
                jnorris10

                 

                "bill.burke@jboss.com" wrote:
                we could possible put this in, but it would not be portable behavior. The spec doesn't require rollback of entity state.


                OK, thanks for the response. I was mistaken and thought this was required by the spec. In your book, EJB 3.0 5th edition (which is awesome btw!), on the last paragraph page 370, it says this:

                "As a transaction monitor, an EJB3 server watches each method call in the transaction. If any of the updates fail, all the updates to the EJBs and entities will be reversed or rolled back." ...


                • 5. Re: Entity bean state not rolled back on TX rollback:
                  jnorris10

                  This is a real pain to workaround since if a transaction is rolled back because of a database deadlock, entities with @GeneratedValue @Ids end up with bogus @Ids since the generated database values have been rolled back in the database, but not in the entities. Therefore, an automatic retry of the transaction will not work because the entities are now technically "detached" entities and em.persist() will fail. Even if full blown entity property rollback isn't implemented, it seems that at the very least @GeneratedValue @Id should be.

                  Here is a possible workaround I can try:
                  1) Mark the entities in the entity graph which do not have @GeneratedValue @Id values set using a @PrePersist entity callback/listener.
                  2) Add an EJB3 Interceptor that wraps the CMT demarcation point. This could catch EJB3TransactionRolledbackException, traverse the entity graph in the EntityManager and unset the @Ids of the marked entities, then rethrow the EJB3TransactionRolledbackException.

                  Does anyone have any better ideas? This solution seems rather dirty. Also, it may not even be possible to get a list of the currently managed entities from the EntityManager (I don't see any interface in EntityManager or org.hibernate.Session).

                  Of course, it sure would be nice to have real entity bean property rollback semantics... ;)

                  • 6. Re: Entity bean state not rolled back on TX rollback:
                    jnorris10

                    Just for any that are interested in this thread, here is what the spec says about this:


                    EJB3 Persistence Specification, page 54

                    3.3.2 Transaction Rollback

                    For both transaction-scoped and extended persistence contexts, transaction rollback causes all pre-existing managed instances and removed instances [15] to become detached. The instances? state will be the state of the instances at the point at which the transaction was rolledback. Transaction rollback typically causes the persistence context to be in an inconsistent state at the point of rollback. Inparticular, the state of version attributes and generated state (e.g., generated primary keys) may be inconsistent.
                    Instances that were formerly managed by the persistence context (including new instances that were made persistent in that transaction) may therefore not be reusable in the same manner as other detached
                    objects?for example, they may fail when passed to the merge operation.[16]

                    ...

                    [16] It is unspecified as to whether instances that were not persistent in the database behave as new instances or detached instances after rollback. This may be implementation-dependent.


                    I personally am curious why full blown @Entity property rollback isn't in the spec. Perhaps in the big picture it's not as useful as I think it is.