Now you're creating new HashMap every request, and, as in your first
example, old bindings get erased. Bind method should be rewritten as

public static void bindThreadObjectContext(ObjectContext context,
String domain) {
        Map<String, ObjectContext> objectContextMap =
threadObjectContext.get();
       if (objectContextMap == null) {
            objectContextMap = Collections.synchronizedMap(new
HashMap<String, ObjectContext>());
            threadObjectContext.set( objectContextMap);

       }
        objectContextMap.put(domain, context);

Or maybe there is something I don't understand :)

2009/9/14 Arnaud Garcia <[email protected]>

> Well, I think there is something I don't understand, I change again
> and, no change..
> now I build a new hash, that I put on the ThreadLocal
>
> I am sorry but I don't understand why...
> Arnaud
>
> code below
>
>
> public class ImagemedBaseContext {
>
>    protected static final ThreadLocal<Map<String, ObjectContext>>
> threadObjectContext = new ThreadLocal<Map<String, ObjectContext>>();
>
>    public static ObjectContext getThreadObjectContext(String domain)
> throws IllegalStateException {
> .......
>  public static void bindThreadObjectContext(ObjectContext context,
> String domain) {
>         Map<String, ObjectContext> objectContextMap =
> Collections.synchronizedMap(new HashMap<String, ObjectContext>());
>         objectContextMap.put(domain, context);
>        threadObjectContext.set(objectContextMap);
>
>
> --------------------------------------------------------------------------------------
> 2009/9/14 Andrey Razumovsky <[email protected]>:
> > Now objectContextMap is static, so only one context is allowed per domain
> > name (for entire app). Map should be created on the fly if needed, in
> bind()
> >
> > 2009/9/14 Arnaud Garcia <[email protected]>
> >
> >> OK, so I just change by adding new ObjectContext to a Map and set/get
> >> this Map from the ThreadLocal which is only as the map created one
> >> time...
> >> But, I still have the same error sometimes....
> >>
> >> below the new code if you can have a quick look...
> >>
> >> many thanks, for help !
> >>
> >> arnaud
> >>
> >>
> ---------------------------------------------------------------------------------------
> >> public class ImagemedBaseContext {
> >>
> >>    private static Map<String, ObjectContext> objectContextMap =
> >> Collections.synchronizedMap(new HashMap<String, ObjectContext>());
> >>     private static final Logger log =
> >> Logger.getLogger(ImagemedBaseContext.class.getName());
> >>     protected static final ThreadLocal<Map<String, ObjectContext>>
> >> threadObjectContext = new ThreadLocal<Map<String, ObjectContext>>();
> >>
> >>    public static ObjectContext getThreadObjectContext(String domain)
> >> throws IllegalStateException {
> >>         ObjectContext context = threadObjectContext.get().get(domain);
> >>         if (context == null) {
> >>            throw new IllegalStateException("Current thread has no
> >> bound ObjectContext.");
> >>         } else {
> >>            log.fine("[GET OBJECT CONTEXT] ObjectContext (" +
> >> context.hashCode() + ") for domain=" + domain + " to ThreadLocal (" +
> >> threadObjectContext.hashCode() + ")");
> >>        }
> >>        return context;
> >>
> >>    }
> >>
> >>    public static void bindThreadObjectContext(ObjectContext context,
> >> String domain) {
> >>         objectContextMap.put(domain, context);
> >>        threadObjectContext.set(objectContextMap);
> >>         if (context == null) {
> >>            log.fine("[UNBIND OBJECT CONTEXT]");
> >>        } else {
> >>            log.fine("[BIND OBJECT CONTEXT] ObjectContext (" +
> >> context.hashCode() + ") for domain=" + domain + " to ThreadLocal (" +
> >> threadObjectContext.hashCode() + ")");
> >>        }
> >>    }
> >> }
> >>
> >>
> ---------------------------------------------------------------------------------------
> >>
> >>
> ---------------------------------------------------------------------------------------
> >>
> >> 2009/9/11 Andrey Razumovsky <[email protected]>:
> >> > Well, looking at your code, I think you should not create new
> ThreadLocal
> >> > each time request is received (in bindThreadObjectContext). You old
> >> bindings
> >> > just get erased
> >> >
> >> > 2009/9/11 Arnaud Garcia <[email protected]>
> >> >
> >> >> Hello,
> >> >>
> >> >> I created a filter to use multi domains in a webapp, but I still have
> >> >> a problem...., I don't find the bug... if someone can help me to fix
> >> >> it !
> >> >> (I think that some people will also need this kind of filter, so this
> >> >> is  why I post the complete code)
> >> >>
> >> >> So, the last bug is that sometimes the ObjectContext cannot be
> >> >> retrieved.....
> >> >> java.lang.IllegalStateException: Current thread has no bound
> >> ObjectContext.
> >> >>     at
> >> >>
> >>
> com.imagemed.cayenne.ImagemedBaseContext.getThreadObjectContext(ImagemedBaseContext.java:39)
> >> >>
> >> >> thanks
> >> >>
> >> >> Arnaud
> >> >>
> >> >>
> >> >> To use the filter:
> >> >> ----------------------
> >> >>
> >> >> =>Declare the filter in web.xml as usual :
> >> >>
> >> >>  <filter>
> >> >>        <filter-name>Imagemed.Cayenne</filter-name>
> >> >>
> >> >>
> >>
>  
> <filter-class>com.imagemed.cayenne.WebApplicationMultiDomainsContextFilter</filter-class>
> >> >>    </filter>
> >> >>
> >> >>    <filter-mapping>
> >> >>        <filter-name>Imagemed.Cayenne</filter-name>
> >> >>        <url-pattern>/*</url-pattern>
> >> >>    </filter-mapping>
> >> >>
> >> >> Then in your DAO you retrieve your contexts from your session like
> this:
> >> >>
> >> >>  ctxtForDomain1 = (DataContext)
> >> >> ImagemedBaseContext.getThreadObjectContext("DOMAIN1");
> >> >>  ctxtForDomain2 = (DataContext)
> >> >> ImagemedBaseContext.getThreadObjectContext("DOMAIN2");
> >> >> ....
> >> >>
> >> >> Below you will find the complete code.....
> >> >>
> >> >>
> >> >> ------------------------------ THE FILTER -------------------------
> >> >> package com.imagemed.cayenne;
> >> >>
> >> >> import java.io.IOException;
> >> >> import java.util.ArrayList;
> >> >> import java.util.Collection;
> >> >> import java.util.logging.Logger;
> >> >> import javax.servlet.Filter;
> >> >> import javax.servlet.FilterChain;
> >> >> import javax.servlet.FilterConfig;
> >> >> import javax.servlet.ServletException;
> >> >> import javax.servlet.ServletRequest;
> >> >> import javax.servlet.ServletResponse;
> >> >> import javax.servlet.http.HttpServletRequest;
> >> >> import javax.servlet.http.HttpSession;
> >> >> import org.apache.cayenne.access.DataContext;
> >> >> import org.apache.cayenne.access.DataDomain;
> >> >> import org.apache.cayenne.conf.Configuration;
> >> >> import org.apache.cayenne.conf.ServletUtil;
> >> >>
> >> >>
> >> >> public class WebApplicationMultiDomainsContextFilter implements
> Filter {
> >> >>
> >> >>    public static final String DATA_CONTEXT_KEY =
> "cayenne.datacontext";
> >> >>    private ArrayList<String> domains = new ArrayList<String>();
> >> >>    private static final Logger log =
> >> >>
> >>
> Logger.getLogger(WebApplicationMultiDomainsContextFilter.class.getName());
> >> >>
> >> >>    public static DataContext getSessionContext(HttpSession session,
> >> >> String domain) {
> >> >>        synchronized (session) {
> >> >>            String dataCtxKey = DATA_CONTEXT_KEY + "." + domain;
> >> >>            DataContext ctxt = (DataContext)
> >> >> session.getAttribute(dataCtxKey);
> >> >>
> >> >>            if (ctxt == null) {
> >> >>                ctxt = DataContext.createDataContext(domain);
> >> >>                session.setAttribute(dataCtxKey, ctxt);
> >> >>            } else {
> >> >>                log.fine("[RETRIEVE] DataContext (" + ctxt.hashCode()
> >> >> + ") retrieved from session key=" + dataCtxKey);
> >> >>            }
> >> >>
> >> >>            return ctxt;
> >> >>        }
> >> >>    }
> >> >>
> >> >>    public void destroy() {
> >> >>    }
> >> >>
> >> >>    public void doFilter(ServletRequest request, ServletResponse
> >> >> response, FilterChain chain) throws IOException, ServletException {
> >> >>        boolean reset = false;
> >> >>
> >> >>        if (request instanceof HttpServletRequest) {
> >> >>            reset = true;
> >> >>
> >> >>            HttpSession session = ((HttpServletRequest)
> >> >> request).getSession(true);
> >> >>            for (String domain : domains) {
> >> >>                DataContext context = getSessionContext(session,
> domain);
> >> >>                ImagemedBaseContext.bindThreadObjectContext(context,
> >> >> domain);
> >> >>            }
> >> >>        }
> >> >>
> >> >>        try {
> >> >>            chain.doFilter(request, response);
> >> >>        } finally {
> >> >>            if (reset) {
> >> >>                for (String domain : domains) {
> >> >>                    ImagemedBaseContext.bindThreadObjectContext(null,
> >> >> domain);
> >> >>                }
> >> >>            }
> >> >>        }
> >> >>    }
> >> >>
> >> >>    public void init(FilterConfig filterConfig) throws
> ServletException {
> >> >>
> >> >>
> >>
>  ServletUtil.initializeSharedConfiguration(filterConfig.getServletContext());
> >> >>        Collection<DataDomain> collDomains =
> >> >> Configuration.getSharedConfiguration().getDomains();
> >> >>        for (DataDomain dataDomain : collDomains) {
> >> >>            domains.add(dataDomain.getName());
> >> >>            log.info("[FOUND DOMAIN] name=" + dataDomain.getName());
> >> >>        }
> >> >>    }
> >> >> }
> >> >>
> >> >> ------------------------------ ImagemedBaseContext
> >> ------------------------
> >> >> package com.imagemed.cayenne;
> >> >>
> >> >> import java.util.Collections;
> >> >> import java.util.HashMap;
> >> >> import java.util.Map;
> >> >> import java.util.logging.Logger;
> >> >> import org.apache.cayenne.ObjectContext;
> >> >>
> >> >> public class ImagemedBaseContext {
> >> >>
> >> >>    private static Map<String, ThreadLocal> threadLocalMap =
> >> >> Collections.synchronizedMap(new HashMap<String, ThreadLocal>());
> >> >>    private static final Logger log =
> >> >> Logger.getLogger(ImagemedBaseContext.class.getName());
> >> >>
> >> >>    public static ObjectContext getThreadObjectContext(String domain)
> >> >> throws IllegalStateException {
> >> >>        ThreadLocal<ObjectContext> threadObjectContext =
> >> >> threadLocalMap.get(domain);
> >> >>        ObjectContext context = threadObjectContext.get();
> >> >>
> >> >>        if (context == null) {
> >> >>            throw new IllegalStateException("Current thread has no
> >> >> bound ObjectContext.");       <============================ ligne 39
> >> >>        } else {
> >> >>            log.fine("[GET OBJECT CONTEXT] ObjectContext (" +
> >> >> context.hashCode() + ") for domain=" + domain + " to ThreadLocal (" +
> >> >> threadObjectContext.hashCode() + ")");
> >> >>        }
> >> >>        return context;
> >> >>
> >> >>    }
> >> >>
> >> >>    public static void bindThreadObjectContext(ObjectContext context,
> >> >> String domain) {
> >> >>        ThreadLocal<ObjectContext> threadObjectContext = new
> >> >> ThreadLocal<ObjectContext>();
> >> >>        threadObjectContext.set(context);
> >> >>        threadLocalMap.put(domain, threadObjectContext);
> >> >>        if (context == null) {
> >> >>            log.fine("[UNBIND OBJECT CONTEXT]");
> >> >>        } else {
> >> >>            log.fine("[BIND OBJECT CONTEXT] ObjectContext (" +
> >> >> context.hashCode() + ") for domain=" + domain + " to ThreadLocal (" +
> >> >> threadObjectContext.hashCode() + ")");
> >> >>        }
> >> >>    }
> >> >> }
> >> >>
> >> >
> >> >
> >> >
> >> > --
> >> > Andrey
> >> >
> >>
> >
> >
> >
> > --
> > Andrey
> >
>



-- 
Andrey

Reply via email to