1 Reply Latest reply: Mar 21, 2012 9:55 AM by JamesSutherland RSS

    TopLink: Persist entity in JPA/DescriptorEventAdapter and Transactions

    923637
      Hi,

      I've to build a kind of 'listener' to save some data on database when an entity changes. Something similar than this example (http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing#Example_AuditedObject_class), altought it's not exactly the same.

      My first approach has been using JPA events like @preUpdate but i've read in the JPA 2.0 Spec (http://download.oracle.com/otn-pub/jcp/persistence-2.0-fr-eval-oth-JSpec/persistence-2_0-final-spec.pdf) that an Entity lifecycle listener should not access EntityManager or execute Query operations (p. 93)

      ----- "+In general, the lifecycle method of a portable application should not invoke EntityManager or Query operations, access other entity instances, or modify relationships within the same persistence context.[43] A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked.+"
      -----

      The first question is: if i use DescriptorEvent class (which as far as i know, is not part of the JPA standard, but it's part of TopLink implementation), does this restriction apply? Or could i safely insert/update database inside DescriptorEvent events?

      And .. if it should work, what happens with transactions? Can i choose whether the event's code works within the same transaction than the entity change or if it's another transaction? Or it'd be in the same transaction?

      Thanks in advance

      Edited by: 920634 on 13-mar-2012 22:21

      Edited by: 920634 on 13-mar-2012 22:21

      Edited by: 920634 on 13-mar-2012 22:21
        • 1. Re: TopLink: Persist entity in JPA/DescriptorEventAdapter and Transactions
          JamesSutherland
          Database access inside events is allowed, whether JPA events or descriptor events, but you need to be careful. Basically you need to understand what you are doing and its affects and are on your own if you screw something up. You must keep in mind that the persistence context is in the process of a commit. So calling persist() or changing objects can have issues, the objects may not get inserted or changes applied depending on the event. Performing direct database access such as native SQL queries is probably safer, but you need to be careful of locks and violating database constraints. You can use insertObject within a UnitOfWork during write events, but you need to be careful.

          Normally you would use the same transaction, if you created a new transaction/EntityManager/UnitOfWork, then you need to be careful or performance, and of deadlocking with yourself.