You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Mike Kienenberger <mk...@gmail.com> on 2010/11/01 14:27:16 UTC

Re: Modified Fields

It's been a while, so I don't remember if it is still relevant for 3.x, but

https://issues.apache.org/jira/browse/CAY-414

contains code for audit logging under Cayenne 2.0.


On Sat, Oct 30, 2010 at 10:49 AM, Bruno René Santos <br...@holos.pt> wrote:
> I only found the hasChanges()... there is, on the other hand, a
> getSnapshot(ObjectId) function. Could I use it to compare to my
> CayenneDataObject, field by field, in order to check which ones were changed?
> This is because I need to create log entries where for each update I only
> specify the key-value pair for the modified fields.
>
> Thanx
> Bruno
>
> -----Mensagem original-----
> De: Michael Gentry [mailto:mgentry@masslight.net]
> Enviada: sexta-feira, 29 de Outubro de 2010 16:59
> Para: user@cayenne.apache.org
> Assunto: Re: Modified Fields
>
> Hi Bruno,
>
> Try dataContext.getObjectStore().getChanges().
>
> mrg
>
>
> On Fri, Oct 29, 2010 at 11:43 AM, Bruno René Santos <br...@holos.pt> wrote:
>> Hello all,
>>
>> Anyone knows how can I know which fields on a CayenneDataObject were modified
>> since the last read?
>>
>> Thanx
>> Bruno Santos
>>
>>
>
>

Re: pre-remove, post-remove

Posted by Andrus Adamchik <an...@objectstyle.org>.
> List<HoMovimentosAplicacoes> movs = new ArrayList<HoMovimentosAplicacoes>();
> for (HoMovimentosAplicacoes mov : apl.getHoMovimentosAplicacoesArray())
> 	movs.add(mov);
> for (int i = 0; i < movs.size(); i++)
> 	apl.removeFromHoMovimentosAplicacoesArray(movs.get(i));
> manager.getContext().deleteObjects(movs);

So do you actually call manager.getContext().commitChanges()? As that's where post-remove is invoked?

> Do I need to remove the objects from the relationships before deleting them or
> just delete them?

This is not needed for deletion to happen, but if you plan on reusing related objects (those that haven't been deleted), you'd better make sure the relationships are clean after commit. So you can either set the delete rules to let Cayenne handle the relationships:

http://cayenne.apache.org/doc12/delete-rules.html

Or you can manually unset them.

Andrus

On Nov 6, 2010, at 5:32 PM, Bruno René Santos wrote:

> I do something like this:
> 
> List<HoMovimentosAplicacoes> movs = new ArrayList<HoMovimentosAplicacoes>();
> for (HoMovimentosAplicacoes mov : apl.getHoMovimentosAplicacoesArray())
> 	movs.add(mov);
> for (int i = 0; i < movs.size(); i++)
> 	apl.removeFromHoMovimentosAplicacoesArray(movs.get(i));
> manager.getContext().deleteObjects(movs);
> 
> Do I need to remove the objects from the relationships before deleting them or
> just delete them?
> 
> Thanx
> Bruno
> 
> -----Mensagem original-----
> De: Andrus Adamchik [mailto:andrus@objectstyle.org] 
> Enviada: sábado, 6 de Novembro de 2010 16:57
> Para: user@cayenne.apache.org
> Assunto: Re: pre-remove, post-remove
> 
> Hi,
> 
> Just found a bit unrelated issue with POST_LOAD callback:
> 
> https://issues.apache.org/jira/browse/CAY-1503
> 
> For your case, it should help if you could post a code example with comments on
> where you are seeing and not seeing the callbacks.
> 
> Andrus
> 
> 
> On Nov 1, 2010, at 8:10 PM, Bruno René Santos wrote:
> 
>> Hello all,
>> 
>> I am having a possibly strange behaviour on my lifecycle callbacks. Imagine de
>> following scenario:
>> 
>> 1 textfield and 1 table on a web application. I fill table with query results
>> depending on the textfield value. Each time i get a valueChange event on the
>> textField I remove all lines from table and create new ones. As each line is a
>> cayennedataobject, each time I do this procedure I call deleteObject for each
>> old line that was removed when new lines are created. In the end I
> commitChanges
>> and only the last lines are saved in relation with the superclass. 
>> 
>> The problem here is the following. For each erased line cayenne call the
>> preremove callback where I create a log for the table removal, in pending
> state.
>> The state of the object is modified (this is the first weird thing, shouldn’t
> be
>> new?) after the preRemove callback the desired process is done but Cayenne
> never
>> calls the postRemove callback on this situation, for other regular deletes
>> everything works.
>> 
>> Anybody recalls a situation where the preXX callback is called but not the
>> postXX? 
>> 
>> Thanx
>> Bruno Santos
>> 
>> 
> 
> 
> 


RE: pre-remove, post-remove

Posted by Bruno René Santos <br...@holos.pt>.
I do something like this:

List<HoMovimentosAplicacoes> movs = new ArrayList<HoMovimentosAplicacoes>();
for (HoMovimentosAplicacoes mov : apl.getHoMovimentosAplicacoesArray())
	movs.add(mov);
for (int i = 0; i < movs.size(); i++)
	apl.removeFromHoMovimentosAplicacoesArray(movs.get(i));
manager.getContext().deleteObjects(movs);

Do I need to remove the objects from the relationships before deleting them or
just delete them?

Thanx
Bruno

-----Mensagem original-----
De: Andrus Adamchik [mailto:andrus@objectstyle.org] 
Enviada: sábado, 6 de Novembro de 2010 16:57
Para: user@cayenne.apache.org
Assunto: Re: pre-remove, post-remove

Hi,

Just found a bit unrelated issue with POST_LOAD callback:

https://issues.apache.org/jira/browse/CAY-1503

For your case, it should help if you could post a code example with comments on
where you are seeing and not seeing the callbacks.

Andrus


On Nov 1, 2010, at 8:10 PM, Bruno René Santos wrote:

> Hello all,
> 
> I am having a possibly strange behaviour on my lifecycle callbacks. Imagine de
> following scenario:
> 
> 1 textfield and 1 table on a web application. I fill table with query results
> depending on the textfield value. Each time i get a valueChange event on the
> textField I remove all lines from table and create new ones. As each line is a
> cayennedataobject, each time I do this procedure I call deleteObject for each
> old line that was removed when new lines are created. In the end I
commitChanges
> and only the last lines are saved in relation with the superclass. 
> 
> The problem here is the following. For each erased line cayenne call the
> preremove callback where I create a log for the table removal, in pending
state.
> The state of the object is modified (this is the first weird thing, shouldn’t
be
> new?) after the preRemove callback the desired process is done but Cayenne
never
> calls the postRemove callback on this situation, for other regular deletes
> everything works.
> 
> Anybody recalls a situation where the preXX callback is called but not the
> postXX? 
> 
> Thanx
> Bruno Santos
> 
> 



Re: pre-remove, post-remove

Posted by Andrus Adamchik <an...@objectstyle.org>.
Fixed in Subversion.

On Nov 10, 2010, at 2:23 PM, Andrus Adamchik wrote:

> Ok, I think this is closer:
> 
> https://issues.apache.org/jira/browse/CAY-1505
> 
> I found this in my own application and am working on a fix now.
> 
> Andrus
> 
> 
> 
> On Nov 6, 2010, at 12:57 PM, Andrus Adamchik wrote:
> 
>> Hi,
>> 
>> Just found a bit unrelated issue with POST_LOAD callback:
>> 
>> https://issues.apache.org/jira/browse/CAY-1503
>> 
>> For your case, it should help if you could post a code example with comments on where you are seeing and not seeing the callbacks.
>> 
>> Andrus
>> 
>> 
>> On Nov 1, 2010, at 8:10 PM, Bruno René Santos wrote:
>> 
>>> Hello all,
>>> 
>>> I am having a possibly strange behaviour on my lifecycle callbacks. Imagine de
>>> following scenario:
>>> 
>>> 1 textfield and 1 table on a web application. I fill table with query results
>>> depending on the textfield value. Each time i get a valueChange event on the
>>> textField I remove all lines from table and create new ones. As each line is a
>>> cayennedataobject, each time I do this procedure I call deleteObject for each
>>> old line that was removed when new lines are created. In the end I commitChanges
>>> and only the last lines are saved in relation with the superclass. 
>>> 
>>> The problem here is the following. For each erased line cayenne call the
>>> preremove callback where I create a log for the table removal, in pending state.
>>> The state of the object is modified (this is the first weird thing, shouldn’t be
>>> new?) after the preRemove callback the desired process is done but Cayenne never
>>> calls the postRemove callback on this situation, for other regular deletes
>>> everything works.
>>> 
>>> Anybody recalls a situation where the preXX callback is called but not the
>>> postXX? 
>>> 
>>> Thanx
>>> Bruno Santos
>>> 
>>> 
>> 
>> 
> 
> 


Re: pre-remove, post-remove

Posted by Andrus Adamchik <an...@objectstyle.org>.
Ok, I think this is closer:

https://issues.apache.org/jira/browse/CAY-1505

I found this in my own application and am working on a fix now.

Andrus



On Nov 6, 2010, at 12:57 PM, Andrus Adamchik wrote:

> Hi,
> 
> Just found a bit unrelated issue with POST_LOAD callback:
> 
> https://issues.apache.org/jira/browse/CAY-1503
> 
> For your case, it should help if you could post a code example with comments on where you are seeing and not seeing the callbacks.
> 
> Andrus
> 
> 
> On Nov 1, 2010, at 8:10 PM, Bruno René Santos wrote:
> 
>> Hello all,
>> 
>> I am having a possibly strange behaviour on my lifecycle callbacks. Imagine de
>> following scenario:
>> 
>> 1 textfield and 1 table on a web application. I fill table with query results
>> depending on the textfield value. Each time i get a valueChange event on the
>> textField I remove all lines from table and create new ones. As each line is a
>> cayennedataobject, each time I do this procedure I call deleteObject for each
>> old line that was removed when new lines are created. In the end I commitChanges
>> and only the last lines are saved in relation with the superclass. 
>> 
>> The problem here is the following. For each erased line cayenne call the
>> preremove callback where I create a log for the table removal, in pending state.
>> The state of the object is modified (this is the first weird thing, shouldn’t be
>> new?) after the preRemove callback the desired process is done but Cayenne never
>> calls the postRemove callback on this situation, for other regular deletes
>> everything works.
>> 
>> Anybody recalls a situation where the preXX callback is called but not the
>> postXX? 
>> 
>> Thanx
>> Bruno Santos
>> 
>> 
> 
> 


Re: pre-remove, post-remove

Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi,

Just found a bit unrelated issue with POST_LOAD callback:

https://issues.apache.org/jira/browse/CAY-1503

For your case, it should help if you could post a code example with comments on where you are seeing and not seeing the callbacks.

Andrus


On Nov 1, 2010, at 8:10 PM, Bruno René Santos wrote:

> Hello all,
> 
> I am having a possibly strange behaviour on my lifecycle callbacks. Imagine de
> following scenario:
> 
> 1 textfield and 1 table on a web application. I fill table with query results
> depending on the textfield value. Each time i get a valueChange event on the
> textField I remove all lines from table and create new ones. As each line is a
> cayennedataobject, each time I do this procedure I call deleteObject for each
> old line that was removed when new lines are created. In the end I commitChanges
> and only the last lines are saved in relation with the superclass. 
> 
> The problem here is the following. For each erased line cayenne call the
> preremove callback where I create a log for the table removal, in pending state.
> The state of the object is modified (this is the first weird thing, shouldn’t be
> new?) after the preRemove callback the desired process is done but Cayenne never
> calls the postRemove callback on this situation, for other regular deletes
> everything works.
> 
> Anybody recalls a situation where the preXX callback is called but not the
> postXX? 
> 
> Thanx
> Bruno Santos
> 
> 


pre-remove, post-remove

Posted by Bruno René Santos <br...@holos.pt>.
Hello all,

I am having a possibly strange behaviour on my lifecycle callbacks. Imagine de
following scenario:

1 textfield and 1 table on a web application. I fill table with query results
depending on the textfield value. Each time i get a valueChange event on the
textField I remove all lines from table and create new ones. As each line is a
cayennedataobject, each time I do this procedure I call deleteObject for each
old line that was removed when new lines are created. In the end I commitChanges
and only the last lines are saved in relation with the superclass. 

The problem here is the following. For each erased line cayenne call the
preremove callback where I create a log for the table removal, in pending state.
The state of the object is modified (this is the first weird thing, shouldn’t be
new?) after the preRemove callback the desired process is done but Cayenne never
calls the postRemove callback on this situation, for other regular deletes
everything works.

Anybody recalls a situation where the preXX callback is called but not the
postXX? 

Thanx
Bruno Santos


RE: Modified Fields

Posted by Bruno René Santos <br...@holos.pt>.
Thanx a lot. I will look into this code.

Regards
Bruno Santos

-----Mensagem original-----
De: jbryanlewis@gmail.com [mailto:jbryanlewis@gmail.com] Em nome de Bryan Lewis
Enviada: segunda-feira, 1 de Novembro de 2010 14:03
Para: user@cayenne.apache.org
Assunto: Re: Modified Fields

I've written code that logs changes to the database.  I'm appending it below
with some disclaimers.  It's stable -- we've been using it in production for
several years now -- but it might be more complicated than you need.  I've
boiled it down somewhat here... removed the frill of ignoring a set of
specified entity and attribute names.  Maybe the only parts you'll care
about are in the first quarter, where it collects all the changed objects
and looks at each one's snapshot.

When you see ModelObject, think CayenneDataObject; ModelObject is my "wedge"
super-class.

    /**
     * For each object in the list of modified, new or deleted objects,
     * write a ChangeHistory record if there was a real change in an
attribute
     * or a to-one relationship.  Called immediately before
dc.commitChanges().
     */
    @SuppressWarnings("unchecked")
    private static void processRealChanges(DataContext dc)
    {
        // Collect all the changed objects together.
        Collection<ModelObject> objects = (Collection<ModelObject>)
dc.newObjects();
        objects.addAll((List<ModelObject>) dc.modifiedObjects());
        objects.addAll((List<ModelObject>) dc.deletedObjects());

        for (ModelObject object : objects) {
            // Get the class name without the "model." prefix.
            ObjEntity entity = object.getObjEntity();
            String entityName = object.getEntityName();
            // If it's new, write a single history record with
            // object.toStringCompact() as the change description.
            if (object.isNew()) {
                String change = object.toStringCompact();
                writeHistory(dc, object, change,
RDChangeType.changeTypeInsert(dc));
                continue;
            }

            // If it's deleted, write a single history record.
            if (object.isDeleted()) {
                String change = object.toStringCompact();
                writeHistory(dc, object, change,
RDChangeType.changeTypeDelete(dc));
                continue;
            }

            // The rest is for modified objects.
            Map snapshot =
dc.getObjectStore().getSnapshot(object.getObjectId());
            List<String> changes = null;
            changes = CollFactory.newList();

            // First the attributes.
            Collection<ObjAttribute> attributes = entity.getAttributes();
            for (ObjAttribute attribute : attributes) {
                String name = attribute.getName();
                Object newValue = object.readProperty(name);

                // The snapshot uses database attribute names.
                String dbName = attribute.getDbAttributePath();
                Object oldValue = snapshot.get(dbName);
                if (valueChanged(oldValue, newValue)) {
                    String desc = null;
                    desc = entityName + "." + name;
                    log.debug("# Real change in attribute " + desc);
                    changes.add(changeDescription(name, oldValue,
newValue));
                }
            }

            // Then the to-one relationships.
            String pkName = null;
            DbEntity dbEntity = entity.getDbEntity();
            Collection<DbAttribute> pks = dbEntity.getPrimaryKeys();
            if (pks.size() == 1) {
                DbAttribute pk = pks.iterator().next();
                pkName = pk.getName();
            }

            for (ObjRelationship relationship : entity.getRelationships()) {
                if (relationship.isToMany()) {
                    continue;
                }

                // Guided by code from cayenne's access.DataRowUtils...
determine
                // whether there was a change by looking at the target
objectId.
                String name = relationship.getName();
                Object targetObject = object.readPropertyDirectly(name);

                // If it's a fault it wasn't modified.
                if (targetObject instanceof Fault) {
                    continue;
                }

                ModelObject toOneTarget = (ModelObject) targetObject;

                // Compare the db values.
                DbRelationship dbRelationship =
relationship.getDbRelationships().get(0);
                DbAttribute dbAttribute =
dbRelationship.getSourceAttributes().iterator().next();
                String sourceAttributeName = dbAttribute.getName();
                Object oldValue = snapshot.get(sourceAttributeName);
                dbAttribute =
dbRelationship.getTargetAttributes().iterator().next();
                String targetAttributeName = dbAttribute.getName();
                Object newValue = null;
                if (toOneTarget != null && (toOneTarget.isPersistent() ||
toOneTarget.isHollow())) {
                    newValue =
toOneTarget.getSnapshotDbProperty(targetAttributeName);
                }

                // Be careful if the newValue is null and the relationship
is based on
                // the source object's PK which can't be null.  For example,
Company.rating
                // is based on the company's PK but not all companies have a
rating.
                boolean ignoreNewNullValue = (newValue == null &&
sourceAttributeName.equals(pkName));
                if (!ignoreNewNullValue && valueChanged(oldValue, newValue))
{
                    changes.add(changeDescription(name, oldValue,
newValue));
                }
            }

            if (changes.size() > 0) {
                Collections.sort(changes);
                String changeDescription =
CString.componentsJoinedByString(changes, "\n");
                writeHistory(dc, object, changeDescription,
RDChangeType.changeTypeUpdate(dc));
            }
        }
    }



On Mon, Nov 1, 2010 at 9:27 AM, Mike Kienenberger <mk...@gmail.com>wrote:

> It's been a while, so I don't remember if it is still relevant for 3.x, but
>
> https://issues.apache.org/jira/browse/CAY-414
>
> contains code for audit logging under Cayenne 2.0.
>
>
> On Sat, Oct 30, 2010 at 10:49 AM, Bruno René Santos <br...@holos.pt>
> wrote:
> > I only found the hasChanges()... there is, on the other hand, a
> > getSnapshot(ObjectId) function. Could I use it to compare to my
> > CayenneDataObject, field by field, in order to check which ones were
> changed?
> > This is because I need to create log entries where for each update I only
> > specify the key-value pair for the modified fields.
> >
> > Thanx
> > Bruno
> >
> > -----Mensagem original-----
> > De: Michael Gentry [mailto:mgentry@masslight.net]
> > Enviada: sexta-feira, 29 de Outubro de 2010 16:59
> > Para: user@cayenne.apache.org
> > Assunto: Re: Modified Fields
> >
> > Hi Bruno,
> >
> > Try dataContext.getObjectStore().getChanges().
> >
> > mrg
> >
> >
> > On Fri, Oct 29, 2010 at 11:43 AM, Bruno René Santos <br...@holos.pt>
> wrote:
> >> Hello all,
> >>
> >> Anyone knows how can I know which fields on a CayenneDataObject were
> modified
> >> since the last read?
> >>
> >> Thanx
> >> Bruno Santos
> >>
> >>
> >
> >
>


Re: Modified Fields

Posted by Bryan Lewis <br...@maine.rr.com>.
I've written code that logs changes to the database.  I'm appending it below
with some disclaimers.  It's stable -- we've been using it in production for
several years now -- but it might be more complicated than you need.  I've
boiled it down somewhat here... removed the frill of ignoring a set of
specified entity and attribute names.  Maybe the only parts you'll care
about are in the first quarter, where it collects all the changed objects
and looks at each one's snapshot.

When you see ModelObject, think CayenneDataObject; ModelObject is my "wedge"
super-class.

    /**
     * For each object in the list of modified, new or deleted objects,
     * write a ChangeHistory record if there was a real change in an
attribute
     * or a to-one relationship.  Called immediately before
dc.commitChanges().
     */
    @SuppressWarnings("unchecked")
    private static void processRealChanges(DataContext dc)
    {
        // Collect all the changed objects together.
        Collection<ModelObject> objects = (Collection<ModelObject>)
dc.newObjects();
        objects.addAll((List<ModelObject>) dc.modifiedObjects());
        objects.addAll((List<ModelObject>) dc.deletedObjects());

        for (ModelObject object : objects) {
            // Get the class name without the "model." prefix.
            ObjEntity entity = object.getObjEntity();
            String entityName = object.getEntityName();
            // If it's new, write a single history record with
            // object.toStringCompact() as the change description.
            if (object.isNew()) {
                String change = object.toStringCompact();
                writeHistory(dc, object, change,
RDChangeType.changeTypeInsert(dc));
                continue;
            }

            // If it's deleted, write a single history record.
            if (object.isDeleted()) {
                String change = object.toStringCompact();
                writeHistory(dc, object, change,
RDChangeType.changeTypeDelete(dc));
                continue;
            }

            // The rest is for modified objects.
            Map snapshot =
dc.getObjectStore().getSnapshot(object.getObjectId());
            List<String> changes = null;
            changes = CollFactory.newList();

            // First the attributes.
            Collection<ObjAttribute> attributes = entity.getAttributes();
            for (ObjAttribute attribute : attributes) {
                String name = attribute.getName();
                Object newValue = object.readProperty(name);

                // The snapshot uses database attribute names.
                String dbName = attribute.getDbAttributePath();
                Object oldValue = snapshot.get(dbName);
                if (valueChanged(oldValue, newValue)) {
                    String desc = null;
                    desc = entityName + "." + name;
                    log.debug("# Real change in attribute " + desc);
                    changes.add(changeDescription(name, oldValue,
newValue));
                }
            }

            // Then the to-one relationships.
            String pkName = null;
            DbEntity dbEntity = entity.getDbEntity();
            Collection<DbAttribute> pks = dbEntity.getPrimaryKeys();
            if (pks.size() == 1) {
                DbAttribute pk = pks.iterator().next();
                pkName = pk.getName();
            }

            for (ObjRelationship relationship : entity.getRelationships()) {
                if (relationship.isToMany()) {
                    continue;
                }

                // Guided by code from cayenne's access.DataRowUtils...
determine
                // whether there was a change by looking at the target
objectId.
                String name = relationship.getName();
                Object targetObject = object.readPropertyDirectly(name);

                // If it's a fault it wasn't modified.
                if (targetObject instanceof Fault) {
                    continue;
                }

                ModelObject toOneTarget = (ModelObject) targetObject;

                // Compare the db values.
                DbRelationship dbRelationship =
relationship.getDbRelationships().get(0);
                DbAttribute dbAttribute =
dbRelationship.getSourceAttributes().iterator().next();
                String sourceAttributeName = dbAttribute.getName();
                Object oldValue = snapshot.get(sourceAttributeName);
                dbAttribute =
dbRelationship.getTargetAttributes().iterator().next();
                String targetAttributeName = dbAttribute.getName();
                Object newValue = null;
                if (toOneTarget != null && (toOneTarget.isPersistent() ||
toOneTarget.isHollow())) {
                    newValue =
toOneTarget.getSnapshotDbProperty(targetAttributeName);
                }

                // Be careful if the newValue is null and the relationship
is based on
                // the source object's PK which can't be null.  For example,
Company.rating
                // is based on the company's PK but not all companies have a
rating.
                boolean ignoreNewNullValue = (newValue == null &&
sourceAttributeName.equals(pkName));
                if (!ignoreNewNullValue && valueChanged(oldValue, newValue))
{
                    changes.add(changeDescription(name, oldValue,
newValue));
                }
            }

            if (changes.size() > 0) {
                Collections.sort(changes);
                String changeDescription =
CString.componentsJoinedByString(changes, "\n");
                writeHistory(dc, object, changeDescription,
RDChangeType.changeTypeUpdate(dc));
            }
        }
    }



On Mon, Nov 1, 2010 at 9:27 AM, Mike Kienenberger <mk...@gmail.com>wrote:

> It's been a while, so I don't remember if it is still relevant for 3.x, but
>
> https://issues.apache.org/jira/browse/CAY-414
>
> contains code for audit logging under Cayenne 2.0.
>
>
> On Sat, Oct 30, 2010 at 10:49 AM, Bruno René Santos <br...@holos.pt>
> wrote:
> > I only found the hasChanges()... there is, on the other hand, a
> > getSnapshot(ObjectId) function. Could I use it to compare to my
> > CayenneDataObject, field by field, in order to check which ones were
> changed?
> > This is because I need to create log entries where for each update I only
> > specify the key-value pair for the modified fields.
> >
> > Thanx
> > Bruno
> >
> > -----Mensagem original-----
> > De: Michael Gentry [mailto:mgentry@masslight.net]
> > Enviada: sexta-feira, 29 de Outubro de 2010 16:59
> > Para: user@cayenne.apache.org
> > Assunto: Re: Modified Fields
> >
> > Hi Bruno,
> >
> > Try dataContext.getObjectStore().getChanges().
> >
> > mrg
> >
> >
> > On Fri, Oct 29, 2010 at 11:43 AM, Bruno René Santos <br...@holos.pt>
> wrote:
> >> Hello all,
> >>
> >> Anyone knows how can I know which fields on a CayenneDataObject were
> modified
> >> since the last read?
> >>
> >> Thanx
> >> Bruno Santos
> >>
> >>
> >
> >
>