cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Arnaud Garcia <arn...@imagemed-87.com>
Subject Re: getThreadObjectContext with domain parameter - code -
Date Tue, 15 Sep 2009 15:18:56 GMT
;-)
many thanks it works well now.

Arnaud

2009/9/14 Andrey Razumovsky <razumovsky.andrey@gmail.com>:
> 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 <arnaud@imagemed-87.com>
>
>> 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 <razumovsky.andrey@gmail.com>:
>> > 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 <arnaud@imagemed-87.com>
>> >
>> >> 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 <razumovsky.andrey@gmail.com>:
>> >> > 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 <arnaud@imagemed-87.com>
>> >> >
>> >> >> 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
>

Mime
View raw message