Announcement Announcement Module
No announcement yet.
Statefulness of Managers for audit/filter purposes Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Statefulness of Managers for audit/filter purposes

    Hello group,

    I've been putting off a design decision for a few weeks now, but it is time to make a choice. Our application uses Spring, Hibernate and Struts and is organized somewhere between PoEAA Domain Model/Service Layer and Fowler's dreaded Anemic Domain Model (which I do not consider all bad, btw). We have stateless Manager classes that mirror business use cases and from the outside are exposed as services (in one app).

    Many of our Manager classes do things (or tell domain objects to do things) that require auditing, filtering or some other "current user" concern. In order to avoid passing the user on 75% of the method calls, I would typically require the user in the Manager's constructor, or pass it to a factory method so that every call has access to the calling user. But with Spring, we can't do that, and besides that introduces state to those Managers.

    So we have two solutions (or three if you break it down):

    1. Make managers stateful (not application/business state though, this is an important distinction)
    a - Instantiate a new copy every request
    b - Hold a reference in user session
    2. Pass the current user on just about every method call to the business logic

    I'm leaning towards 1a. I don't like 1b becuase every fiber of my being says don't stuff unnecessary crap into user session. I don't like 2 because it pollutes the method signatures and opens the API up to misuse.

    My questions:

    1. Am I missing a possible solution here?
    2. Do you reckon 1a is the way to go?
    3. What do you suppose the performance tradeoff between 1a and 1b are? CPU hit to instantiate lots of objects vs. memory hit to retain many long-lived copies?

    Thanks in advance. I couldn't find anything concrete in this forum, the Spring manual or PetClinic. If I missed a section, please point me in the right direction.


  • #2
    Hi Man, U can pass your User Object using ThreadLocal. So u may not need to build a stateful "Manager".


    • #3
      What's wrong with 2? If Manager needs to operate on a User instance, the User instance is a legitimate parameter. I wouldn't consider it polluting.

      Consider a garage a stateless service on cars. Guess what, you do have to bring over your car everytime when it needs some service.

      ThreadLocal is a viable solution, too, IMO.


      • #4
        Consider a garage a stateless service on cars. Guess what, you do have to bring over your car everytime when it needs some service.
        This analogy is a bit flawed -- it actually supports solution 1. I have to bring my car (domain object) to the garage (business method) every time I go because the garage works on many cars. I surely don't have to provide a mechanic (the current user) ... he works there!

        Another reason I lean away from passing it in every request is that it is subject to misuse. If a filter condition must be applied based on an authenticated user, it should be applied always and IMHO automatically.

        I think ThreadLocal is the way to go here, I'm going to try that route.

        Thanks, everyone!



        • #5
          Just curious, why are you contemplating doing this? What is wrong with solutions like container managed security, or Acegi Security?


          • #6
            The security model itself isn't the issue per se; rather how to get information about the current user to the business logic. With that said, we did evaluate form-based security and also Acegi (which possibly addresses this with AOP), but I did not do that research myself.

            My own gripe about container managed (from what I have read) is that you get only two levels of control, rather than three. By that I mean the model consists of Users and Roles. To effectively manage security, I need Users, Roles and Permissions. My concept of a Permission is a bit like the CMS version of Roles. In my model, you manage Permissions through roles, and at runtime, check only against a given Permission. This adds the benefit of being able to redefine Roles as a configuration concern and program to more granular Permissions.

            The developer who looked at Acegi decided it was a bit complex at a time when we were just adopting Spring. That is about all I can comment on since I got the quick overview of his reading and not much detail. If there's a good resource I should take a look at regarding the API, I'll do so in my own time.

            Thanks for your interest,



            • #7
              Statefulness of Managers for audit/filter purposes

              Actually, with ACEGI and ACL (Access Control Lists) configured properly, you can do object instance based securities, method security, and have access to the security token if you wish to get the currently logged on user straight from the secureContext. Since the current user is a security concern, it would probably be best to allow the security framework to let your application / domain code know who it is.

              Another option is to have the security framework contain other information about the user in the secure context. You can decorate the user object which is stored in the secure context if you have additional information you wish to store with the security token. What we are currently doing is getting the current user fomr the security system (ACEGI), then loading that user from our domain model if we need to get non-security information (what department they are in, phone numbers, trouble tickets, etc.).

              The contacts sample with the new spring release has more info on how to configure this.