Patterns: Entity bean audit trail

Discussions

EJB programming & troubleshooting: Patterns: Entity bean audit trail

  1. Patterns: Entity bean audit trail (5 messages)

    Folks,

    Is there an established design pattern for setting up audit trails for entity beans? I thought I'd better check before launching into my own design.

    Basically, I want to record every update to a given bean type in a seperate, "shadow" table. I was considering just defining a new bean, and using the session facade to copy the values across after every update to the main bean type. It's not very elegant, but it's easy enough to do.

    I'd be open to any better suggestions.
  2. I think, EJB doesn't have that functionality. Implementing it from the database side using trigger will be much easier and effective.

    I think ejb should come up with a new functionality like "Triggers", becaue, it already has relationships, cascade delete and all.

    Thanks,
    Senthil.
  3. I'm not looking for EJB itself to handle this, I'm just looking for a design pattern that I can use to achieve the desired effect.

    I was hoping that XDoclet provided such functionality, but no such luck :-(
  4. Oh, and database triggers aren't an option in this case, I'm lumbered with MySQL 4, which doesn't support triggers.
  5. Hi,
    If you havse some DAOs for the stuff you want to audit you could make a set of AuditDAOs and AuditWrapperDAOs implementations. AuditDAOs just log the audits in the 'shadow' table. A call on an AuditWrappersDAOs will split into a call to a DAOImpl and a call to a AuditDAO. You can configure your dao factory to return DAOImpls or AuditWrapperDAOs, depending if the auditing is on/off.
    Best regards, Mircea
  6. How about this one? I haven't tried this yet. I just had this idea. I am not
      sure will it work.
    Assumptions:
    1. Audit implementation does not participate in any transaction of the business
      flow. <br>
      2. Audit will be done as asychoronously, errors on audit will be reported in
      a TABLE or log file. This is to improve the performance.
    <br>
      Steps:<br>
      1. Develop and Implement the business logic in session facade as synchronous<br>
      2. Implement the Audit logic in Message facade as Asynchronous<br>
      3. Have a wrapper method in the session facade, that is going to be the business
      interface method for the client, iside the method first invoke the actual business
      implementation with transaction and after successful, invoke the audit method
      on the MDB.
    <br>
      Example:

    public interface MoneyTransferFacade extends EJBObject {<br>
      public void transfer(MoneyTransferDTO dto) throws RemoteException, AccountException;<br>
      }
    public class MoneyTransferFacadeBean implements SessionBean {<br>
      .....
    public void transfer(MoneyTransferDTO dto) throws Exception {<br>
                transferActual(dto);<br>
                transferAudit(dto);<br>
      }
    // This is the method actually implements the business logic. So set the transaction
      attribute only to this method, ex: requiresNew
    public void transferActual(MoneyTransferDTO dto) throws AccountException {<br>
      // Here call the Entity Beans ot DAO methods.<br>
      try{<br>
          Account.deposit(dto.toAccount, dto.money);<br>
          Acctount.withdraw(dto.fromAccount, dto.money);<br>
      catch(Exception ex) {<br>
          ctx.setRollBackOnly();<br>
          throw new AccountException();<br>
      }<br>
      }
    // This is to invoke the MDB, So, don't set any transactional attribute to
      this method.<br>
      public void transferAudit(MoneyTransferDTO dto) {<br>
      <br>
      // Here create a Object Message with MoneyTransferDTO and send it to MDB<br>
      }<br>
      .....<br>
      }
    MDB:<br>
      public class MessageMoneyTransferAudit implements MessageDrivenBean, MessageListener
      {
    .....
    public void onMessage(Message msg) {<br>
             ObjectMessage om = (ObjectMessage) msg;<br>
      try {<br>
             MoneyTransferDTO dto = (MoneyTransferDTO) om.getObject();<br>
      // Here invoke the Entity Bean or DAO
    }<br>
      catch(JMSException ex) {
    // On exception invoke ErrorLogBean to report, which maps to a Error_Log_Table<br>
           ErrorLog.log();<br>
      }<br>
      }
    .....<br>
      }
    DAOs or EntityBeans:
    Account ==> Maps to ACCOUNT_TABLE<br>
      AccountAudit ==> Maps to ACCOUNT_AUDIT table

    Thanks,
    Senthil.