Re: Question about localObjects()

From: Borut Bolčin (bo..ajdi.si)
Date: Fri Aug 18 2006 - 02:32:42 EDT

  • Next message: Andreas Pardeike: "Getting more info from a query when exception is thrown"

    Hello,

    I was searching the archives on what would be the best way to move
    objects between data contexts. Beside
    http://cwiki.apache.org/CAYDOC/moving-objects-between-contexts.html I
    found this thread and as I don't have much experience in moving objects,
    I wonder what the current recommendation is? Are there different
    approaches for some scenarios (web application, standalone application)
    or is there one best way of doing it?

    Thanks!
    Borut

    On 30.12.2005 7:20, Andrus Adamchik wrote:
    > Hi Marcin,
    >
    > I was on vacation and didn't read the mailing list for a while. During
    > that time I came up with a solution that is closer to what DataContext
    > does. It is somewhat similar to what you suggest, but relies on
    > ClassDescriptor.copyProperties. It does not involve serialization or
    > class generation. I just checked in this code to CVS, it will be in
    > the 12/30/2005 nightly build. Let me know how this worked.
    >
    > Andrus
    >
    >
    > On Dec 23, 2005, at 5:57 AM, Marcin Skladaniec wrote:
    >
    >> 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
    >>
    >>
    >

    -- 
    bLOG <http://www.delo.si/blog/borutb/>
    --
    Naključna *izjava tedna* iz tednika Mladina:
    



    This archive was generated by hypermail 2.0.0 : Fri Aug 18 2006 - 02:33:10 EDT