Re: Bug in child contexts?

From: Kevin Menard (kmenar..ervprise.com)
Date: Tue Mar 04 2008 - 13:16:44 EST

  • Next message: Mike Kienenberger: "Re: Queries"

    On 3/4/08 12:59 PM, "Andrus Adamchik" <andru..bjectstyle.org> wrote:

    >
    > On Mar 4, 2008, at 7:24 PM, Kevin Menard wrote:
    >
    >> So, in this case, I use localObject to pull customer into
    >> childContext, set the relationship, commit, and go on my merry way.
    >
    > This is the correct way and AFAIK it should work. Could you post a bit
    > longer code example, that shows localObject call as well as the
    > problem? Just to doublecheck that you are not swapping a customer
    > reference somewhere, before we start digging the DataContext code.

    Sure. This code is from a T4 webapp. There are two page classes at play
    here. One is a base class using template methods to consolidate logic for
    two semi-related pages. I've removed the portions that clearly are not
    relevant:

    public abstract class AccountCreationPage extends ApplicationPage
    {
       ..ersist
        public abstract Addressable getAddressable();
        public abstract void setAddressable(final Addressable a);

       ..verride
        public void pageBeginRender(final PageEvent event)
        {
            // If the address hasn't been set for this instance already, then
    set it
            // to the customer's first shipping info address.
            if (null == getAddressable())
            {
                final ObjectContext objectContext =
    getVisit().getCustomerDataContext().createChildDataContext();

                final Addressable addressable = (Addressable)
    objectContext.newObject(getAddressableClass());
                final Address address =
    addressable.getObjectContext().newObject(Address.class);

                addressable.setAddress(address);

                setAddressable(addressable);
            }
        }

        public void add(final IRequestCycle cycle)
        {
            // Grab the billing/shipping info and put the customer into the same
    context to
            // make relationship operations easier.
            final Addressable a = getAddressable();
            final Customer c = (Customer)
    a.getObjectContext().localObject(getVisit().getCustomer().getObjectId(),
    null);

            // Associate the billing/shipping info with the customer.
            addToCustomer(c, a);

            // Commit the changes to the DB.
            c.getObjectContext().commitChanges();
        }
    }

    public abstract class AddShippingInfo extends AccountCreationPage
    {
       ..verride
        protected void addToCustomer(final Customer c, final Addressable a)
        {
            c.addToShippingInfo((ShippingInfo) a);
            c.setDefaultShippingInfo((ShippingInfo) a);
        }
    }

    In the debugger, right after the commit of c, I can see both the local
    customer and the session-persisted one (stored in the Visit). These two
    customers have different contexts. The session one has
    "customerDataContext" and the local one has "childContext." Calling
    getShippingInfo() on either returns ShippingInfo instances registered with
    "childContext." It should be noted that the initial state is no shipping
    info persisted or otherwise associated with the customer. So, all shipping
    info are in the same context, but they're not necessarily the same as the
    customer.

    (Apologies for switching from billing to shipping info. They're of the same
    structure and I just realized I changed on you.)

    Thanks,
    Kevin



    This archive was generated by hypermail 2.0.0 : Tue Mar 04 2008 - 13:19:04 EST