RE: takeValuesFromDictionary: equvalent

From: JR Ruggentaler (j..pv.com)
Date: Mon Aug 19 2002 - 00:14:10 EDT

  • Next message: JR Ruggentaler: "set method fails on relationship"

    Andrus,
            thanks for the updateValues() method. I think it would be a good
    addition to the framework. I am having a problem with the relationships.
    After I call updatesValues() and save the changes my relationship does not
    get set in the database. I even tried calling the Entities set (setAddress)
    method and I doesn't make a difference. Here is a small piece of the code

    // Plan not found create plan
    if (null == plan)
    {
            plan = new Plan();
            ctxt.registerNewObject(plan, "Plan");
            plan.updateValues(insMstr);
            plan.setAddress(address);
            ctxt.commitChanges();
    }

    Is there any reason you can think of why the framework would not save the
    foreign key in the source table?

    J.R.
    -----Original Message-----
    From: Andrus [mailto:andru..bjectstyle.org]
    Sent: Friday, August 16, 2002 5:25 PM
    To: JR Ruggentaler; JR Ruggentaler; Cayenne-User (E-mail)
    Subject: RE: takeValuesFromDictionary: equvalent

    It is a bit tougher if you also want to copy the relationships while
    maintaing consistent object graph.

    >If my
    >CayenneDataObject has a relationship to another CayenneDataObject what
    >should the key and value be for the relationship be in my Map instance that
    >I am using in props.putAll(map)? The relationship name and an instance of
    >the related CayenneDataObject?

    Yes, but see below.

    >What about to many relationships a List
    >containing instances of the related CayenneDataObject?

    To be able to do lazy fetching of to-many, we use a special List
    implementation called "ToManyList". When you register a new object with
    context, all to-many relationships are tracked and assigned an empty
    ToManyList. So I guess when copying is done, you must have custom logic
    that would take a list from your map, find corresponding list in the
    object, and replace all its contents:

    List newList = (List)map.get(nextKey);
    List existingList = (List)this.params.get(nextKey);
    if(existingList != null) {
        existingList.clear();
        existingList.addAll(newList);
    }

    Now, the above approach will NOT take care of reverse relationships to an
    object. Take a look at CayenneDataObject source code for cleaner ways to do
    object graph management. Relevant methods are:

    addToManyTarget
    setToOneTarget
    setToOneDependentTarget

    Here is a resulting "clean" method. I haven't tested or even compiled it,
    so let me know if this works at all, we might add this to Cayenne.

    public MyDataObject extends CayenneDataObject {
        public void updateValues(Map map) {
            // we are modified...
            if(persistenceState == PersistenceState.COMMITTED) {
                 persistenceState = PersistenceState.MODIFIED;
            }

             ObjEntity e =
    dataContext.lookupEntity(getObjectId().getObjEntityName());
            Iterator it = map.keySet().iterator();
            while(it.hasNext()) {
                String key = (String)it.next();
                Object val = map.get(key);
                if(e.getAttribute(key) != null) {
                     params.put(key, val);
                }
                else if(e.getRelationship() != null) {
                    ObjRelationship r = (ObjRelationship)e.getRelationship();
                    if(r.isToMany()) {
                         List newList = (List)val ;
                         List existingList = (List)params.get(key);
                         existingList.clear();
                          Iterator listIt = newList .iterator();
                         while(listIt.hasNext()) {
                              DataObject o = (DataObject)listIt.next();
                               addToManyTarget(key, o, true);
                         }

                    }
                    else if(r.isToDependentEntity()) {
                       setToOneDependentTarget(key, (DataObject)val);
                    }
                    else {
                       setToOneTarget(key, (DataObject)val, true);
                    }
                }
            }
        }
    }



    This archive was generated by hypermail 2.0.0 : Mon Aug 19 2002 - 00:14:01 EDT