1 2 Previous Next 19 Replies Latest reply on Oct 15, 2007 7:17 PM by griffitm

    Audit Interceptor with State

    kevin.genie

      Hi,

      What will be the best way to implement a Audit Log feature with Seam + EJB3 entity beans? I have read thru several docs but was unable to find a way to pass state to the interceptor. By state what i mean is some data that is specific to the context. (For ex, the currently logged in user. I have to set the current user information to the Audit log). One way I tried and worked was that let all the entity beans extend from a Base Entity and the BaseEntity entity has the callback methods. Also, make all the entity beans Seam components including Base Entity. So in the Base Entity callback method, I can do a Contexts.getSessionConetxt.get("currentUser") and set the usee_id to the createdBy or lastModifiedBy fields.
      But the problem is how will i get the current state of the the entity fields in call back (or in listener) for audit purpose because we will only get the changed values that are going to be flushed ?

      Also, is an entity listener is thead safe to be used with multiple entities? Like in the above scenario, if i have annotated the Base Entity with one listener class, then for every entity a new listener object will be created ?

      Thanx

      Kevin

        • 1. Re: Audit Interceptor with State
          pmuir

          I implemented something similar to the audit log code on the hibernate website. It's an extension to EntityHome, and will scan over the entity being saved, logging new values (and old values if changed and an update is occuring) if the property is marked @Auditable. It will follow associations depending on the CascadeType and works with collections. Oh, and it outputs the log as a trinidad tree table, but thats easily customisable.

          I can post the code if you are interested (but beware, it's mostly complete and mostly works but I'm sure there are lots of bugs...)

          • 2. Re: Audit Interceptor with State
            cwash

            I'm interested in this type of functionality, too. In the past I've used a Hibernate Interceptor and had an extension to my base model object that encapsulated the fields I wanted audited. I was able to do a type check in the interceptor code and persist the encapsulated audit log entries there.

            Too much of a Seam n00b to have done this yet, though.

            • 3. Re: Audit Interceptor with State
              kevin.genie

              Hello,

              Can u pls post ur code ? Again, how will i persist the audit data from the interceptor / listener ? (i.e how do i get a entitymanager for that ? look up the entitymanager factory and get the em ?)

              Thanx

              Kevin

              • 4. Re: Audit Interceptor with State
                pmuir

                Well I didn't do this through an interceptor/listener, but via an extension of EntityHome from the Seam Framework. I just override the persist, update, remove methods in EnitityHome, call my audit logger, and then continue as normal. So, the only extra thing you need is a separate EntityManager instance for accessing the old version of the object for comparison (just configure another ManagedPersistenceContext in components.xml).

                I'm just tidying the code a bit to make it more useable, and stripping the presentation stuff out (as that uses trinidad) and then I'll post it - probably tomorrow.

                • 5. Re: Audit Interceptor with State
                  kevin.genie

                  Hello,

                  I was just reading through the EntityHome Manager pattern and it seems that for that to work I have to use SeamManagedPersistenceContext. In my application we are not using SeamManagerPersistenceContext and are relying on EJB container for Tx demarcation. In this case, what will be the options left ?

                  Thanx,

                  Kevin

                  • 6. Re: Audit Interceptor with State
                    gavin.king

                    This stuff is meant to be used with Seam-managed tx/pc. If you wanted to use it with container-managed PC/tx, you could do it, but you would need to inject the EntityHome into a session bean component that does tx demarcation.

                    • 7. Re: Audit Interceptor with State
                      gavin.king

                      (The reason is that fine-grained method-level tx demarcation is an antipattern - you want to do all your work for a request in the same tx.)

                      • 8. Re: Audit Interceptor with State
                        kevin.genie

                        Hello Gavin,
                        <<(The reason is that fine-grained method-level tx <<demarcation is an antipattern - you want to do all <<your work for a request in the same tx.)

                        I didn't understand what you have said ? Can u pls give a detailed explanation ? Are you referrring to the pattern where from the controller you are forced to do all the work in a single ejb call since you cannot make two EJB calls in the same Action method because of Tx getting splitted ? If that is the case, is there a way this can be done in Seam ? If we are using Session bean methods as action methods, then here also we have to do all the work in that method itself; am i right ?

                        Thanx

                        Kevin

                        • 9. Re: Audit Interceptor with State
                          pmuir

                          Back to the original topic of audit logging. Here is my code. I'm pretty sure there are bugs in the logging code (especially in the list comparison) so if you spot stuff please let me know.

                          http://wiki.jboss.org/wiki/Wiki.jsp?page=SeamAuditHome

                          • 10. Re: Audit Interceptor with State
                            kevin.genie

                            Thanks very much. I was on vacation. I am going to work on it today itself.

                            • 11. Re: Audit Interceptor with State
                              gavin.king

                               

                              "kevin.genie" wrote:
                              Hello Gavin,
                              <<(The reason is that fine-grained method-level tx <<demarcation is an antipattern - you want to do all <<your work for a request in the same tx.)

                              I didn't understand what you have said ? Can u pls give a detailed explanation ? Are you referrring to the pattern where from the controller you are forced to do all the work in a single ejb call since you cannot make two EJB calls in the same Action method because of Tx getting splitted ? If that is the case, is there a way this can be done in Seam ? If we are using Session bean methods as action methods, then here also we have to do all the work in that method itself; am i right ?


                              What I mean is that if you let EJB demarcate the txn, and if you have lots of little calls from the view to the session beans while rendering a single page, you will get many little transactions instead of a single big one.

                              • 12. Re: Audit Interceptor with State
                                kevin.genie

                                Thanks very much Gavin, for spending time in explaining that.

                                For the auditing part, I am now trying to do it thru Hibernate SessionFactory level Interceptor.

                                • 13. Re: Audit Interceptor with State
                                  awhitford

                                  So in the end, how did you do this Kevin? Did you use Pete's strategy, or end up using Hibernate Interceptors?

                                  • 14. Re: Audit Interceptor with State

                                    Heya Pete--

                                    I'm trying to use your solution (from here http://wiki.jboss.org/wiki/Wiki.jsp?page=SeamAuditHome)...

                                    I copied the orm.xml into my project and annotated a bunch of stuff in my User object as @Auditable. When I start up my app server (OC4J), the auditlog and auditlogdetail tables are created, but when I update my user objects (with entityManager.merge()...is that a problem?), nothing is inserted into the audit tables.

                                    Is there something else I need to add to my application to make this work? It's probably something to do with what you wrote on the wiki: "As long as you control your entities through an AuditHome? (a drop in replacement for EntityHome?) logs will be created."...I don't know how to do this, though.

                                    Any direction would be appreciated,

                                    --Rich

                                    1 2 Previous Next