Re: Any way to check if object has really changed?

From: Andrey Razumovsky (razumovsky.andre..mail.com)
Date: Tue Mar 24 2009 - 09:59:29 EDT

  • Next message: Bryan Lewis: "Re: Any way to check if object has really changed?"

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

    /**
         *..eturn были ли изменения в объекте
         */
        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 <mgentr..asslight.net>

    > 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
    > <razumovsky.andre..mail.com> 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 <mgentr..asslight.net>
    > >
    > >> 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
    > >> <razumovsky.andre..mail.com> 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
    > >> >
    > >>
    > >
    >



    This archive was generated by hypermail 2.0.0 : Tue Mar 24 2009 - 10:00:10 EDT