Please help: retrieval and proper usage of per thread DataContext

From: Joseph Hannon (jah.volcan..mail.com)
Date: Mon Nov 28 2005 - 18:32:00 EST

  • Next message: Andrus Adamchik: "Re: Dates inserted into Oracle do not have Minutes / Seconds?"

    I would really appreciate help on this. I am too near production release to
    have this issue and am now concerned. I have included my code below for
    reference by the following questions. Not sure my DataContext (DC)
    retrieval code is doing what I think. I am using Tapestry 4.0 beta 11,
    Cayenne 1.2M8, Hivemind 1.1 RC1 running on Linux and Jetty 5.1.5.

    I setup my DC retrieval using the WebApplicationContextProvider approach and
    a HiveMind service where each thread gets its own DC. My code calls my
    singleton Utility class below and gets acces to the DC that way.
    Persistence does work most of the time, and then, for some reason, I will
    have problems with persistence. Not sure what exactly triggers the problem
    whether it is refreshing the browser, multiple sessions from multiple
    browsers, not sure yet. It would appear that when the problem occurs, there
    are two different DCs involved. I am creating an object in request A, then
    adding data to it and persisting in request B. Is that allowed? Do I need
    to do something different?

    Related? Sometimes I will get an exception from my DB about inserting null
    fields and Cayenne says it attempted: INSERT INTO bggoodies.ORDER (FIELD_A,
    FIELD_B, FIELD_C) VALUES (?, ?, ?) [bind: NULL, NULL, NULL]. I know the
    values were put into the object and then its like they are missing during
    persistence. Is this the case of two different DCs not seeing the same
    data?

    I thought that using Hivemind to retrive a DC service would make this a per
    thread DC thing. If I can't get this to work, I may go after the Session DC
    approach and skip Hivemind. When running multiple tests requesting DCs,
    seems like the service is alternating between two reused DCs most of the
    time. That doesn't make sense to me. I would expect a different DC for
    every thread/request.

    Is my handling of a null DC in <<DataContextServiceImpl.java>> below
    correct? Doesn't seem correct and it does happen frequently.

    Any suggestions and identification of errors would be greatly appreciated!

    Joseph

    <<hivemodule-datacontext.xml>>

    <?xml version="1.0" encoding="utf-8"?>

    <module id="datacontext" package="foo.bar.hivemind" version="1.0.0">

       <service-point id="DataContextService" interface="DataContextService">
          <!-- Specifying a model seemed like the only way I could get this to
    work -->
          <invoke-factory model="threaded"> <!--model= primitive | singleton |
    threaded | pooled-->
          <!--<invoke-factory>-->
             <construct class="DataContextServiceImpl"/>
          </invoke-factory>
       </service-point>

    </module>

    <<DataContextService.java>>

    package foo.bar.hivemind;

    import org.objectstyle.cayenne.access.DataContext;

    public interface DataContextService
    {
       public DataContext getDataContext () ;

    }

    <<DataContextServiceImpl.java>>

    package foo.bar.hivemind;

    import org.objectstyle.cayenne.access.DataContext;
    import org.apache.log4j.Logger;
    import foo.bar.utility.Utility;

    public class DataContextServiceImpl implements DataContextService
    {
       Logger log = Utility.fetchLogger(DataContextServiceImpl.class) ;

       public DataContextServiceImpl()
       {
          log.debug ("Called.") ;
       }

       public DataContext getDataContext()
       {
          log.debug ("Called.") ;

          DataContext dataContext = null ;

          try
          {
             dataContext = DataContext.getThreadDataContext() ;
          }
          catch (IllegalStateException e)
          {
             log.info ("Current thread has no bound DataContext.") ;
          }

          if (dataContext == null)
          {
             log.info ("Current thread has NULL DataContext- Creating.") ;
             dataContext = DataContext.createDataContext() ;
             DataContext.bindThreadDataContext(dataContext) ;
          }

          return dataContext ;

       }

    }

    <<Singleton Utility class>>

    ...

    private static Registry hivemindRegistry ;

    private Utility()
    {
       log.info ("Constructing HiveMind Registry for DataContext.") ;
       hivemindRegistry = ExampleUtils.buildRegistry("hivemodule-datacontext.xml")
    ;
    }

    public static DataContext fetchDataContext ()
    {
       DataContextService dcs = (DataContextService) hivemindRegistry.getService
    (DataContextService.class) ;
       DataContext dc = dcs.getDataContext() ;
       log.debug ("DataContext:\n'" + dc.toString()) ;

       return dc ;

    }

    public static void commitChanges ()
    {
       Utility.fetchDataContext().commitChanges(Level.ALL) ;

    }

    public static void registerNewObject (DataObject dataObject)
    {
       Utility.fetchDataContext().registerNewObject(dataObject) ;

    }

    ...

    <<web.xml>>

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
        version="2.4">

       <distributable/>

       <filter>...</filter>

       <filter-mapping>...</filter-mapping>

       <listener>
          <listener-class>
    org.objectstyle.cayenne.conf.WebApplicationContextProvider</listener-class>
       </listener>

       <servlet>...</servlet>

       <servlet-mapping>...</servlet-mapping>

       <session-config>...</session-config>

    </web-app>



    This archive was generated by hypermail 2.0.0 : Mon Nov 28 2005 - 18:32:01 EST