You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Marcin Skladaniec <ma...@ish.com.au> on 2007/08/15 07:53:25 UTC

ROP, flattened relationships and no-reverse relationship and/or dotemplates

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.crea 
teToOneProperty(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

Re: ROP, flattened relationships and no-reverse relationship and/or dotemplates

Posted by Andrus Adamchik <an...@objectstyle.org>.


On Aug 15, 2007, at 7:17 PM, Aristedes Maniatis wrote:

> Is it still a design goal to merge some of classes between client  
> and server, particularly the fact that objEntities have different  
> superclasses?

Yes it is. In fact POJO support on the server theoretically makes it  
(almost?) possible now.

As an aside, fully preserving generic DataObjects support (at least  
on the server) alongside POJO is a big competitive advantage over any  
other ORM framework (except for EOF that has this as well).

Andrus

Re: ROP, flattened relationships and no-reverse relationship and/or dotemplates

Posted by Aristedes Maniatis <ar...@maniatis.org>.
On 15/08/2007, at 11:11 PM, Andrus Adamchik wrote:

> 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

Is it still a design goal to merge some of classes between client and  
server, particularly the fact that objEntities have different  
superclasses?

Ari Maniatis



-------------------------->
Aristedes Maniatis
phone +61 2 9660 9700
PGP fingerprint 08 57 20 4B 80 69 59 E2  A9 BF 2D 48 C2 20 0C C8



Re: ROP, flattened relationships and no-reverse relationship and/or dotemplates

Posted by Andrus Adamchik <an...@objectstyle.org>.
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
>>
>
>


Re: ROP, flattened relationships and no-reverse relationship and/or dotemplates

Posted by Andrus Adamchik <an...@objectstyle.org>.
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.cr 
> eateToOneProperty(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
>