Re: DataContext synchronization bug ?

From: Bryan Lewis (brya..aine.rr.com)
Date: Tue Aug 29 2006 - 17:52:36 EDT

  • Next message: Jonathan Bélisle: "Re: DataContext synchronization bug ?"

    This might not help much, but... I've been wrestling with a somewhat
    similar issue, and it turned out to be a silly bug of my own. I wasn't
    committing in the right DataContext. I'm reminded of that when you say
    "Still not working" after trying Marcin's suggestion of touching some
    attribute of the localObject. If it's still not saving after that,
    maybe the object isn't in the DataContext you're committing. Could you
    print the list of updated objects in the DC just before the commit?
    Something like this:

            Collection objects = dc.newObjects();
            objects.addAll(dc.modifiedObjects());
            objects.addAll(dc.deletedObjects());

            Iterator it = objects.iterator();
            while (it.hasNext()) {
                log.debug(it.next());
            }

    Jonathan Bélisle wrote:
    > Hi,
    >
    > Still not working.
    > Is it the normal behavior of localObject() or is it a bug ?
    > It seems to me that there should be a way to copy a modified object to
    > a different dataContext
    > while keeping it's modification info.
    >
    > Maybe I'm not doing it the right way.
    > Maybe localObject() is not the right way.
    >
    > Somebody know the right way ?
    >
    > Jonathan
    >
    >
    > Marcin Skladaniec wrote:
    >> Hi
    >> I'm not using localObject with prototype at the moment. I had some
    >> problems with it as well.
    >> Please try after doing localObject retouching some attribute, like
    >> dataObjectInContext2.setName(getName()), commit and see if this will
    >> put to the database only the new name.
    >>
    >> Marcin
    >>
    >> On 29/08/2006, at 10:53 AM, Jonathan Bélisle wrote:
    >>
    >>> Hi,
    >>>
    >>> It should work but it does not.
    >>>
    >>> context2.commitChanges() won't send an update statement to the
    >>> database if the object was modified in context1.
    >>>
    >>> I think it's not working because context2 was not notified of the
    >>> changes made to dataObject while it was in context1.
    >>>
    >>> Is it working for you ?
    >>> Try the code from the previous post. You will see that nothing gets
    >>> written to the database on commit.
    >>> If it does well..... there's something wrong somewhere :)
    >>>
    >>> Jonathan
    >>>
    >>>
    >>> Marcin Skladaniec wrote:
    >>>> Hello !
    >>>>
    >>>> I think you have it all right, but just in case:
    >>>> dataObjectInContext2=
    >>>> context2.localObject(dataObjectInContext1.getObjectId(),
    >>>> dataObjectInContext1);
    >>>> dataObjectInContext2.setPersistenceState(dataObjectInContext1.getPersistenceState()
    >>>> ); //In case that the object 1 state is NEW
    >>>> context2.commitChanges();
    >>>> Is it that dead simple or you are doing some more things ?
    >>>> I don't see a reason why it is not working for you.
    >>>> Marcin
    >>>>
    >>>>
    >>>> On 29/08/2006, at 4:49 AM, Jonathan Bélisle wrote:
    >>>>
    >>>>> Hi Marcin,
    >>>>>
    >>>>> I've already looked at localObject() and it's not good.
    >>>>> Here's why ?
    >>>>>
    >>>>> You have a data object : dataObjectInContext1
    >>>>> You modify a property : dataObjectInContext1.setName("the new name");
    >>>>> You copy it to the second dataContext and modify it's
    >>>>> persistenceState
    >>>>>
    >>>>> dataObjectInContext2=
    >>>>> context2.localObject(dataObjectInContext1.getObjectId(),
    >>>>> dataObjectInContext1);
    >>>>>
    >>>>> dataObjectInContext2.setPersistenceState(PersistenceState.MODIFIED);
    >>>>>
    >>>>> Everything is ok till now but here is the problem :
    >>>>>
    >>>>> dataObjectInContext2.commitChanges();
    >>>>>
    >>>>> Nothing will be written to the database because context2 did not
    >>>>> track changes of dataObjectInContext2.
    >>>>> That's why i'm not using localObject().
    >>>>> Is there a way that dataObjectInContext2 will be committed using
    >>>>> localObject() ?
    >>>>>
    >>>>> I'm using Cayenne 1.2
    >>>>>
    >>>>> Jonathan.
    >>>>>
    >>>>>
    >>>>> Marcin Skladaniec wrote:
    >>>>>> Hello Jonathan
    >>>>>>
    >>>>>> Please take a closer look on the localObject() method.
    >>>>>> Straight from javadocs :
    >>>>>> "Returns an object local to this DataContext and matching the
    >>>>>> ObjectId. If prototype is not null, local object is refreshed
    >>>>>> with the prototype values.
    >>>>>>
    >>>>>> In case you pass a non-null second parameter, you are responsible
    >>>>>> for setting correct persistence state of the returned local
    >>>>>> object, as generally there is no way for Cayenne to determine the
    >>>>>> resulting local object state."
    >>>>>>
    >>>>>> If you have still problems please mention what version of cayenne
    >>>>>> are you using.
    >>>>>>
    >>>>>> Marcin
    >>>>>> -------------------------->
    >>>>>> ish
    >>>>>> http://www.ish.com.au
    >>>>>> Level 1, 30 Wilson Street Newtown 2042 Australia
    >>>>>> phone +61 2 9550 5001 fax +61 2 9550 4001
    >>>>>>
    >>>>>>
    >>>>>> On 28/08/2006, at 6:33 AM, Jonathan Bélisle wrote:
    >>>>>>
    >>>>>>> Hi, maybe someone can help me here.
    >>>>>>>
    >>>>>>> I'm trying to copy a dataObject to another dataContext while
    >>>>>>> keeping
    >>>>>>> it's modified state so that it will be correctly committed to
    >>>>>>> the db by the second dataContext.
    >>>>>>>
    >>>>>>> Let say we have an entity with an attribute Name and a
    >>>>>>> relationship Category.
    >>>>>>> The object 1000001 exist in the db and has a Name and a Category
    >>>>>>>
    >>>>>>> //Create the dataContext
    >>>>>>> DataContext dc1= DataContext.createDataContext();
    >>>>>>> DataContext dc2= DataContext.createDataContext();
    >>>>>>>
    >>>>>>> //Get object from db. Modify the name.
    >>>>>>> Animal from= (Animal) DataObjectUtils.objectForPK(dc1, new
    >>>>>>> ObjectId("Animal", "animalId", 1000001));
    >>>>>>> from.setName("XXX" + new SecureRandom().nextInt());
    >>>>>>>
    >>>>>>> //Get local object to dc2
    >>>>>>> //I cannot use dc2.localObject(from.getObjectId(), from);
    >>>>>>> //because the dc2 won't see the modification made in dc1.
    >>>>>>> Animal to= (Animal) dc2.localObject(from.getObjectId(), null);
    >>>>>>> dc2.getObjectStore().resolveHollow(to);
    >>>>>>>
    >>>>>>> //Copy the attributes from object1 to object2 String attName;
    >>>>>>> ObjAttribute objAttribute;
    >>>>>>> ObjEntity objEntity=
    >>>>>>> from.getObjectContext().getEntityResolver().lookupObjEntity(to);
    >>>>>>> Iterator attributes = objEntity.getAttributes().iterator();
    >>>>>>> while (attributes.hasNext()) {
    >>>>>>> objAttribute = (ObjAttribute) attributes.next();
    >>>>>>> attName= objAttribute.getName();
    >>>>>>>
    >>>>>>> to.writeProperty(attName, from.readPropertyDirectly(attName));
    >>>>>>> }
    >>>>>>> dc2.commitChanges();
    >>>>>>>
    >>>>>>> System.out.println(from);
    >>>>>>> System.out.println(to);
    >>>>>>>
    >>>>>>> Everything is committed correctly to the db but the object from
    >>>>>>> has now a Category = null
    >>>>>>>
    >>>>>>> The problem is after the dc2.commitChanges() and
    >>>>>>> it comes from
    >>>>>>> org.objectstyle.cayenne.event.EventManager.DispatchThread.run()
    >>>>>>> witch is firing an event to set the relationship Category to null.
    >>>>>>> I don't know why it is doing that.
    >>>>>>> I am doing something wrong ? Is it a bug in cayenne ?
    >>>>>>> And i need context synchronization so turning it off is not an
    >>>>>>> option.
    >>>>>>>
    >>>>>>> I really need help on this one, can someone help me ?
    >>>>>>>
    >>>>>>> Jonathan
    >>>>>>
    >>>>>>
    >>>>>>
    >>>>>>
    >>>>>>
    >>>>>>
    >>>>>>
    >>>>>
    >>>>
    >>>> -------------------------->
    >>>> ish
    >>>> http://www.ish.com.au
    >>>> Level 1, 30 Wilson Street Newtown 2042 Australia
    >>>> phone +61 2 9550 5001 fax +61 2 9550 4001
    >>>>
    >>>>
    >>>>
    >>>>
    >>>>
    >>>
    >>
    >> -------------------------->
    >> ish
    >> http://www.ish.com.au
    >> Level 1, 30 Wilson Street Newtown 2042 Australia
    >> phone +61 2 9550 5001 fax +61 2 9550 4001
    >>
    >>
    >>
    >>
    >>
    >



    This archive was generated by hypermail 2.0.0 : Tue Aug 29 2006 - 17:53:07 EDT