Ok, this is fixed - client side should now work as before.
I am also looking into making one-way to-many client relationships
updateable, just like they are on the server.
Andrus
On Aug 15, 2007, at 8:18 AM, Andrus Adamchik wrote:
Hmm... this may be a bug in implementation. "Runtime" reverse
relationships (i.e. the relationships that Cayenne created on the
fly) would only work on CayenneDataObjects that can store arbitrary
stuff in the internal values map. Client side objects that use Java
fields to store properties (and do not use enhancement like JPA
POJOs) definitely can't take advantage of this feature (although I
suspect it may still work when the data crosses back to the
server). So I'll need to exclude "runtime" relationships from the
client schema. Let me work on that.
Andrus
On Aug 15, 2007, at 1:53 AM, Marcin Skladaniec wrote:
Hello
I think recently the requirement every relationship to be defined
both ways was revoked.
I found few problems with it:
we have defined (to many, read only):
<obj-relationship name="sessions" source="Course" target="Session"
deleteRule="Nullify" db-relationship-path="CourseClasses.sessions"/>
it looks like cayenne creates fake relationship called
runtimeRelationship0 which fails during runtime :
[java] 14:36:38,192 [btpool0-1 ] INFO
org.apache.cayenne.remote.service.BaseRemoteService :157 - error
processing message
[java] java.lang.NoSuchFieldException: runtimeRelationship0
[java] at java.lang.Class.getDeclaredField(Class.java:1854)
[java] at
org.apache.cayenne.reflect.FieldAccessor.lookupFieldInHierarchy
(FieldAccessor.java:154)
[java] at
org.apache.cayenne.reflect.FieldAccessor.lookupFieldInHierarchy
(FieldAccessor.java:163)
[java] at
org.apache.cayenne.reflect.FieldAccessor.lookupFieldInHierarchy
(FieldAccessor.java:163)
[java] at
org.apache.cayenne.reflect.FieldAccessor.prepareField
(FieldAccessor.java:101)
[java] at org.apache.cayenne.reflect.FieldAccessor.<init>
(FieldAccessor.java:50)
[java] at
org.apache.cayenne.reflect.PersistentDescriptorFactory.createAccessor
(PersistentDescriptorFactory.java:191)
[java] at
org.apache.cayenne.reflect.valueholder.ValueHolderDescriptorFactory.c
reateToOneProperty(ValueHolderDescriptorFactory.java:70)
[java] at
org.apache.cayenne.reflect.PersistentDescriptorFactory.getDescriptor(
PersistentDescriptorFactory.java:99)
[java] at
org.apache.cayenne.reflect.PersistentDescriptorFactory.getDescriptor(
PersistentDescriptorFactory.java:51)
[java] at
org.apache.cayenne.reflect.ClassDescriptorMap.createDescriptor
(ClassDescriptorMap.java:122)
as a workaround a reverse relationship can be created (to one,
read only) :
<obj-relationship name="course" source="Session" target="Course"
db-relationship-path="courseClass.course"/>
It does work ok than, with a small problem. We have also
customised the dotemplates (templates to generate the cayenne
classes).
within them we are using loop to create a generic setValueForKey
(key, value) method for classes on client (this is an equivalent
of writeProperty(key, value) on server):
#foreach( $rel in ${objEntity.DeclaredRelationships})
#if (!$rel.ToMany)
if (${stringUtils.capitalizedAsConstant($rel.Name)}
_PROPERTY.equals(key)) { set${stringUtils.capitalized($rel.Name)}
( (${importUtils.formatJavaType
($rel.TargetEntity.ClientClassName)}) value); return; }
#end
#end
but we don't want to iterate through the "read-only" relationships.
Any hint how to do that ?
Marcin