Announcement Announcement Module
Collapse
No announcement yet.
hibernateTemplate, entityInterceptor with state and threading Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • hibernateTemplate, entityInterceptor with state and threading

    Hello, I have an interceptor for audit-logging that basically sets two fields modified_by and created_by. For example,

    public void update(DomainEntity entity, Integer userId) {
    template.update(audited(entity, userId));
    }

    private DomainEntity audited(DomainEntity entity, Integer userId) {
    template.setEntityInterceptor(new AuditInterceptor(userId));
    return entity;
    }

    So I create a new Interceptor with the userId in question and set it on the template for each auditable DAO-operation. I am worried that there is a concurrency issue her, in that two threads may set the interceptor on the same template, messing things up.

    What is the best solution to avoid this ? the userId is state that the interceptor needs to know about. Any alternative designs ?

  • #2
    Please use [ code][/code ] tags when posting code, that way it remains readable.

    For starters don't use HibernateTemplate/HibernateDaoSupport it isn't recommended anymore (since about 2007!). EntityInterceptors/Listeners should be singletons because they are shared by the sessions. Basically what I would do, create a Interceptor or Listener which reads a threadlocal which holds the userId for that thread. That way there is no problem having a single interceptor/listener, instead of creating a new instance you simply have to set the userId for the current session and cleanup afterwards (important in a web container as threads get reused!!!)

    Comment


    • #3
      Thanks, where should the ThreadLocal variable live ? In the DAO ? Could it live in the interceptor itself ?

      Comment


      • #4
        I suggest taking a peak on how ThreadLocals work by looking at either springs transactionmanagement or spring security.

        Basically

        1) Create a UserIdHolder class, which wraps a ThreadLocal
        2) In the dao or service, call the Holder to set the id
        3) in the interceptor call the holder to get the id
        4) after the method call (either in the dao) clear the id from the UserIdHolder.

        Comment

        Working...
        X