Sure, here it is. Sorry for Russian comments :) It probably needs more work
for complicated mappings, but works fine for mine

/**
     * @return были ли изменения в объекте
     */
    private boolean hasChanged(CayenneDataObject cdo) {
        DataContext context = (DataContext) cdo.getObjectContext();

        if (cdo.getPersistenceState() != PersistenceState.MODIFIED) {
//вероятно, NEW
            return true;
        }

        DataRow snapshot =
context.getObjectStore().getCachedSnapshot(cdo.getObjectId());
        if (snapshot == null) { //похоже на новый объект
            return true;
        }

        /**
         * Сначала проверяем атрибуты
         */
        ObjEntity entity = cdo.getObjEntity();
        for (ObjAttribute attr : entity.getAttributes()) {
            DbAttribute dba = attr.getDbAttribute();
            if (!Util.nullSafeEquals(snapshot.get(dba.getName()),
cdo.readPropertyDirectly(attr.getName()))) {
                return true;
            }
        }

        /**
         * Проверяем отношения to-one
         */
        for (ObjRelationship rel : entity.getRelationships()) {
            if (!rel.isFlattened() && !rel.isToMany()) {
                DbRelationship dbr = rel.getDbRelationships().get(0);
                String dbid = dbr.getJoins().get(0).getSource().getName();

                Object obj = cdo.readPropertyDirectly(rel.getName());

                if (obj == null) {
                    if (snapshot.get(dbid) != null) { //объект был, но
сброшен в null
                        return true;
                    }
                }
                else if (obj instanceof Persistent) {
                    Persistent p = (Persistent) obj;
                    if (p.getPersistenceState() == PersistenceState.NEW) {
                        return true;
                    }
                    if (p.getPersistenceState() ==
PersistenceState.COMMITTED) {
                        return false;
                    }

                    String dbval = String.valueOf(snapshot.get(dbid));
                    String objval = "" + DataObjectUtils.pkForObject(p);

                    if (!Util.nullSafeEquals(dbval, objval)) {
                        return true;
                    }

                }
            }
        }

        return false;
    }

2009/3/24 Michael Gentry <[email protected]>

> I totally misread that!  I guess I need more caffeine this morning.  A
> long time ago I dug through the code that checked for changes, but I'd
> have to go look at it again.  If you want to share the code, it might
> help others in the future.
>
> mrg
>
>
> On Tue, Mar 24, 2009 at 9:46 AM, Andrey Razumovsky
> <[email protected]> wrote:
> > I have a reverse problem :) Artist is marked as change, and in fact it is
> > not. I've wriiten an implementation of comparing to snapshot, can post if
> > someone'll find it useful
> >
> > 2009/3/24 Michael Gentry <[email protected]>
> >
> >> Well, the Artist object didn't really change.  Could you override
> >> Artist's addToPaintings() (don't forget to call super) and record
> >> somewhere that a change has been made?
> >>
> >> mrg
> >>
> >>
> >> On Tue, Mar 24, 2009 at 6:16 AM, Andrey Razumovsky
> >> <[email protected]> wrote:
> >> > Imagine you have Artist and Painting entities. You create a new
> Paining
> >> and
> >> > attach it to existing Artist, then commit. The Artist object is marked
> as
> >> > modified, so LifecycleListeners will fire for it, but in fact nothing
> >> > changed in DB table (ARTIST). Is there any way to check if object has
> >> really
> >> > changed? I suppose I could iterate through all attrs and simple to-one
> >> rels
> >> > during lifecycle event, and compare values with cached snapshot of the
> >> CDO,
> >> > but this seems to be an ugly way..
> >> >
> >> > Thanks,
> >> > Andrey
> >> >
> >>
> >
>

Reply via email to