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.andre..mail.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 <arnau..magemed-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.andre..mail.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 <arnau..magemed-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
>
This archive was generated by hypermail 2.0.0 : Mon Sep 14 2009 - 11:35:54 EDT