Re: Question about localObjects()

From: Marcin Skladaniec (marci..sh.com.au)
Date: Thu Dec 22 2005 - 21:57:50 EST

  • Next message: emre.yilma..r.net: "OutOFMemory Java heap exeception"

    Hi Andrus !

    On 19/12/2005, at 8:21 PM, Andrus Adamchik wrote:

    >
    > This is another omission in the API. I'll make sure this is added
    > in the next milestone. For now you can do something like that
    > (untested!) -
    >
    > Persistent clone = (Persistent) Util.cloneViaSerialization(object);
    > clone.setObjectContext(otherContext);
    > otherContext.getGraphManager().registerNode(clone.getObjectId(),
    > clone);
    >

    I investigated this bit of code and found that PersistentObjects are
    not Serializable...
    I made an ugly, but working approach to make them serializable. Added
    few lines to client-superclass.vm:
    (You can see that two first methods are only modified methods from
    CayenneDataObject)

    private void writeObject(ObjectOutputStream out) throws IOException {
            out.writeInt(getPersistenceState());

            switch (getPersistenceState()) {
                // New, modified or transient or deleted - write the
    whole shebang
                // The other states (committed, hollow) all need just
    ObjectId
                case PersistenceState.TRANSIENT:
                case PersistenceState.NEW:
                case PersistenceState.MODIFIED:
                case PersistenceState.DELETED:

                    out.writeObject(getPropertyHashtable());
                    break;
            }

            out.writeObject(getObjectId());
        }

        private void readObject(ObjectInputStream in) throws IOException,
                ClassNotFoundException {
            this.setPersistenceState(in.readInt());

            switch (getPersistenceState()) {
                case PersistenceState.TRANSIENT:
                case PersistenceState.NEW:
                case PersistenceState.MODIFIED:
                case PersistenceState.DELETED:

                    setPropertyMap((Map)in.readObject());
                    break;
                case PersistenceState.COMMITTED:
                case PersistenceState.HOLLOW:
                           this.setPersistenceState(PersistenceState.HOLLOW);
                    // props will be populated when required
    (readProperty called)
                    setPropertyMap(new HashMap());
                    break;
            }

            this.setObjectId((ObjectId) in.readObject());

            // DataContext will be set *IF* the DataContext it came from
    is also
            // deserialized. Setting of DataContext is handled by the
    DataContext
            // itself
        }

            public Map getPropertyMap() {
                    Hashtable t=new Hashtable() ;
    #foreach( $attr in ${objEntity.DeclaredAttributes} )
                    if (get${stringUtils.capitalized($attr.Name)}() != null) {
                            t.put(${stringUtils.capitalizedAsConstant($attr.Name)}_PROPERTY,
    get${stringUtils.capitalized($attr.Name)}());
                    }
    #end
    #foreach( $rel in ${objEntity.DeclaredRelationships} )
                    if (get${stringUtils.capitalized($rel.Name)}() != null) {
                         t.put(${stringUtils.capitalizedAsConstant($rel.Name)}
    _PROPERTY, get${stringUtils.capitalized($rel.Name)}());
                 }
    #end
                    return t;
            }
            
            public void setPropertyMap(Map map) {
            #foreach( $attr in ${objEntity.DeclaredAttributes} )
                    if (map.containsKey(${stringUtils.capitalizedAsConstant($attr.Name)}
    _PROPERTY)) {
                            set${stringUtils.capitalized($attr.Name)}
    ( ($importUtils.formatJavaType(${attr.Type})) map.get($
    {stringUtils.capitalizedAsConstant($attr.Name)}_PROPERTY));
                    }
            #end
            }

    My idea :
    - add get/setPropertyMap() methods with empty bodies to PersistentObject
    - add get/setPropertyMap() methods to client-superclass.vm
    - add read/writeObject() to PersistentObject
    and voila, serialization, and (and therefore localObjects()) works
    for 3t
    What do you think ? Is there a better solution ?

    Cheers
    Marcin Skladaniec



    This archive was generated by hypermail 2.0.0 : Thu Dec 22 2005 - 21:57:53 EST