Re: DataContext synchronization bug ?

From: Jonathan Bélisle (jonathan.belisl..cda.ca)
Date: Tue Aug 29 2006 - 19:50:52 EDT

  • Next message: Craig L Russell: "Re: GlassFish"

    I printed the list of updated objects and my object is there with the
    persistance state to MODIFIED.
    And I am committing the right dataContext : dataContext2

    Event then, committing one or the other data context should write the
    changes to the database.

    Bryan Lewis wrote:
    > 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 - 19:51:15 EDT