Re: Saving a single object

From: Mikaël Cluseau (nwr..wrk.dyndns.org)
Date: Tue May 10 2005 - 20:39:05 EDT

  • Next message: Andrus Adamchik: "Re: Saving a single object"

    Thanks for the hints. Just a thing : I think I still need the snapshots
    to compare the commited and current version, right?

    Here is a new, safer version :

    public static void singleSave(DataObject o) {
            // Perform the single save
            DataContext c = DataContext.createDataContext(o.getDataContext()
                            .getParentDataDomain().getName());

            boolean refetch = false;
            DataObject newObject;
            switch (o.getPersistenceState()) {
            case NEW:
                    newObject = c.createAndRegisterNewObject(o.getClass());
                    copyModifiedAttributes(o, newObject);
                    refetch = true;
                    break;
            case MODIFIED:
                    newObject = DataObjectUtils.objectForPK(c, o.getObjectId());
                    copyModifiedAttributes(o, newObject);
                    refetch = true;
                    break;
            case DELETED:
                    newObject = DataObjectUtils.objectForPK(c, o.getObjectId());
                    c.deleteObject(newObject);
                    break;
            default:
                    throw new InvalidParameterException("Cannot singleSave() "
                                    + PersistenceState.persistenceStateName(o
                                                    .getPersistenceState()) + " data objects");
            }
            c.commitChanges();
            if (refetch) {
                    o.getDataContext().refetchObject(o.getObjectId());
            }
    }

    private static void copyModifiedAttributes(DataObject from, DataObject to) {
            DataContext context = from.getDataContext();
            ObjEntity entity = context.getEntityResolver().lookupObjEntity(from);

            Map<String, ?> committed = context.getObjectStore().getCachedSnapshot(
                            from.getObjectId());
            Map<String, ?> current = context.currentSnapshot(from);

            for (Object it : entity.getAttributes()) {
                    final String attr = ((ObjAttribute) it).getName();
                    final String dbAttr = ((ObjAttribute) it).getDbAttributeName();

                    if (committed == null) { // Mainly for NEW objects
                            to.writeProperty(attr, current.get(dbAttr));
                    } else { // For MODIFIED objects
                            Object value = committed.get(dbAttr);
                            if (value != current.get(dbAttr)) {
                                    to.writeProperty(attr, value);
                            }
                    }
            }
    }

    Mikael.

    Le mardi 10 mai 2005 à 09:31 -0400, Andrus Adamchik a écrit :
    > A few comments on the implementation:
    >
    > 1. This line should probably be called after commit changes:
    >
    > o.setPersistenceState(PersistenceState.COMMITTED);
    >
    > (for deleted case it should be "unregisterObjects" instead)...
    >
    > 2. Copy method will not work if DB columns have names different from
    > object properties (i.e. DbAttribute names are not the same as
    > ObjAttributes), as snapshot key names are using DbAttributes for naming. I
    > guess just iterating through attributes and doing "readProperty" /
    > "writeProperty" on source and destination objects would be the easiest way
    > to go about it.
    >
    >
    > Andrus



    This archive was generated by hypermail 2.0.0 : Tue May 10 2005 - 20:39:12 EDT