Hi Kevin,
CayenneDataObject approach is fundamentally different from other
persistent object implementations that are all variations of POJO. So
I think a different approach may work better - using current client
objects on the server (instead of using current server objects on the
client).
Andrus
On Nov 7, 2007, at 8:07 AM, Kevin Menard wrote:
I just spent the better part of this evening trying to get
something going.
Unfortunately, I'm stuck at the moment and it's getting pretty late
(or
early) here. So, I'm just posting what I tried and what my results
were.
If anyone else wants to suggest something, great, if not, I'll prod
at it
more when I can get some time. I'll likely have to defer it and
come up
with some workaround, because I need this portion of the app
relying on the
fix done.
Anyway . . .
I took a really naïve approach to start because I just wanted to get
something going.
* Made CayenneDataObject extends PersistentObject
** Removed any code duplication
* Updated my data map to use the same class name for the server and
client
classes for all obj entities.
* Modified the velocity template to combine both server and client
class
info:
* Static property name fields appear as before
* All client fields appear
* All methods perform an instanceof check on the context to choose the
appropriate code to call like so:
public BillingInfo getDefaultBillingInfo() {
if (objectContext instanceof CayenneContext) {
if(objectContext != null) {
objectContext.prepareForAccess(this,
"defaultBillingInfo",
true);
}
return (BillingInfo) defaultBillingInfo.getValue();
}
else {
return (BillingInfo)readProperty("defaultBillingInfo");
}
}
Problems:
* Retrieving data from client fails during deep merge on toMany
relationships. The read property is null causing most of the rest
of the
method to fail.
* Adding NPE checks for the above gets me to a workable state, but the
generated class does not work as expected. In particular, all the
values
are in the map (like they should for a server) and all the fields
are blank
(which should not be the case for the client).
My initial thoughts were that the failures were due to the above code
snippet failing to do the right thing if the context is null (is
there a
better way to tell if we're executing on the client?). But, the first
failure occurs well before any of those accessors are called. So,
I am a
bit at a loss.
Anyway, if Ari or someone else wants to help out with this, I'd
certainly
welcome it.
--
Kevin
On 10/27/07 1:01 PM, "Andrus Adamchik" <[EMAIL PROTECTED]> wrote:
Would be nice if we could make it work... IIRC back in the day when
ROP was first implemented there were a number of limitations
preventing DataContext and CayenneDataObject from being used on the
client, mostly related to the fact that both had direct dependencies
on the structure of the underlying stack (e.g. referencing DataDomain
and DataNode). Now we are *mostly* free of those. So I'd be curious
to try and use DataContext on the client.
A few issues to pay attention to:
* Serialization. Current client objects are more lightweight as they
store their properties in Java fields, vs. a Map used by
CayenneDataObject. So probably a custom serializer is needed.
* While supporting a single class hierarchy is a good idea,
preserving the ability for separate hierarchies is very important -
users may not want to expose some server methods to the client, and
generally may want to have two sets of objects with different
behavior.
In any event it is a good idea to reevaluate our options now.
Andrus
On Oct 27, 2007, at 7:20 PM, Kevin Menard wrote:
Hi all,
I've just gone back to work on a ROP application I have and am
again running
into the issue of having to duplicate code between the server model
subclasses and the client model subclasses. I've got a way of
working
around that, but I'm thinking this is probably best handled by
Cayenne. In
particular, I really don't think that there should be two class
hierarchies
for what amounts to a boolean field (remote/not remote).
I think the generated superclass should perform the duty of calling
the
appropriate method for reading and writing properties. I think
this would
advocate adding an isRemote() method to the ObjectContext interface
to avoid
having to do instanceof operations.
There would have to be some sort of unification between
PersistentObject and
CayenneDataObject as well. My naïve guess is that the latter could
extend
the former, but I haven't investigated whether or not they are
compatible.
Does this sound like a reasonable approach? If so, I'll probably
dig in on
that.
Thanks,
Kevin