I am so glad we had this opportunity to dig into what it takes to open up the stack to SOA... :-)

On Jul 13, 2006, at 6:24 AM, Michael Victorov wrote:
Server  side:

-  Knows  from  config  how  to  map  database  tables  to  XML schema
structures.  (Currently  Cayenne maps DB to Java classes, so we change
it to schema complex types).

We have a ClientServerChannel class that works as a server-side translation layer for Hessian. If we can create a similar class that does "persistent object to XML and back" translation, it would be awesome. Essentially we need to convert each object to a Map with an ObjectId attached in some form.

-  Can  process  queries  (brought  from  net). Serverside keeps query
results in something like CayenneDataObject.

This won't even require refactoring - Cayenne supports it already:

http://objectstyle.org/confluence/display/CAYDOC/Generic+Persistent +Class

But I think the key is serialization mechanism that devises properties from the model (DataMap) and extracts them from the object at hand using ClassDescriptor interface available from server EntityResolver. This way it will work regardless of whteher a generic object is used or a specific Java class with server-side business logic.


-  Can  dynamicaly produce WSDL with configured objects (...from DB to
schema mapping...) in it's schema part.

I still like to entertain the idea of a generic data service that does not need a new WSDL definition when the schema changes. But I also like your idea of WSDL serving as an EntityResolver to the client. And I don't think the two contradict each other :-) My +1 on that.


-  Can  serialize  that (...something like to...) CayenneDataObject to
actual XML types as declared in schema and configuration.


Client side:

-  Knows  from  config  how  to  map  schema objects to Java (or other
language) types and how to bring remoting functionality to them.

- Can deserialize these schema types straight to their Java mappings.


So what we have:

- No client-side language classes at serverside.
- Client do not need to work with Cayenne-specified things like
ObjectIds etc.
- To write client on other language we need to regenerate from WSDL
business-logic classes and classes to make queries. We need not to
generate Cayenne classes hierarchy.

What is bad:
- Too many things to refactor.


Comments...???

Actually it doesn't look like too many things to refactor. Everything you outlined can be done as a thin layer on top of the existing Cayenne stack (see the ClientServerChannel and generic object comments above). If we limit the queries (at least for now) to just NamedQuery with parameters, queries become trivial. ObjectId handling can be skipped for queries too.



However what is overlooked here is update capability. Even if we don't do it now, we have to plan the design to accommodate it in the future. Essential interface that defines logical responsibilities of a Cayenne client is DataChannel:

http://objectstyle.org/confluence/display/CAYDOC/DataChannel

Our design ignores "getEventManager" method (which is ok, let's keep ignoring it), replaces "getEntityResolver" with the WSDL (which is great), and addresses "onQuery". It does not address "onSync", i.e. the update part. This is probably the most non-SOA'ish piece as it requires a smart context on the client that tracks object changes and submits the diffs for commit (and brings back the diffs generated by the server on commit, such as generated PKs).

I am open to discussion on this. The choices that I see are:

* Ignore it for the purpose of this project :-)
* Define simple serialization formats (or data transfer objects) for GraphDiff and ObjectId. Both are just maps of values after all. This of course is what requires client to be smart. * Pass around the entire objects instead of diffs. This approach, while inefficient, is much more portable and reduces the requirements for the client (if an object is new or dirty, send it back to the server to figure out the changes). This leaves the question of how we handle deleted objects (so at least a desired persistent state will have to be attached to an object), and how do we pass back generated keys for the new objects (we can make it a requirement for the client to provide the key??)

Andrus



Reply via email to