You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Andrew Lindesay <ap...@lindesay.co.nz> on 2010/11/17 19:12:44 UTC

Read Property Behaviour (CAY-1512)

Hello;

I've been playing around with trying to override some behaviours in the 
area of "read property" on the data objects, but I think I have come to 
the conclusion that the way it is rigged-up makes this a little 
difficult.  I'd like to suggest a change (which is probably more 
appropriate for 3.1 owing to it being a non-trivial change in behaviour) 
and I would be interested in any feedback.  Here is the text of the 
ticket...

---

There is an issue that a data object (DO) uses the "readProperty()" 
method in its accessors such as "getStartTimestamp()"/"getArtist()" 
etc... The "readNestedProperty()" does some extra things like using 
reflection to get at non-modelled accessors, but "readProperty()" does 
not.  This is an inconsistency.

Simply adding the additional reflection to "readProperty()" is not a 
good idea because in the case where an object is not yet related to the 
model, an infinite loop can result.  Particularly in the case where a 
data object is not yet added to an object context, the logical condition 
around stopping this infinite loop is not able to be identified.

My suggestion is to add a protected "readPropertyStored()" which will be 
used by the accessors such as "getStartTimestamp()"/"getArtist()".  This 
method will ~not~ use reflection, but "readProperty()" will do the 
additional reflection if necessary.  The "readPropertyStored()" will 
continue to invoke "readPropertyDirectly()".

In addition, the "extra reflection" from "readProperty()" would be 
serviced through two additional methods on the data object;

      readPropertyDerived(..)

For the case of the "readNestedProperty(..)" the use of reflection into 
an object which is ~not~ a data object will be serviced through;

      readNestedPropertyFromNonDataObject(..)
	
Together these changes will allow for consistenecy in the 'read 
property' behaviour and will also allow third parties to more easily 
extend Cayenne's 'read property' behaviors in order to support more 
sophisticated 'read property' behaviour.

This is a change in behavior and generated DAO classes would need to be 
modified to use 'readPropertyStored()' instead of 'readProperty()'.

---

cheers.

-- 
Andrew Lindesay
www.silvereye.co.nz

Re: Read Property Behaviour (CAY-1512)

Posted by Andrus Adamchik <an...@objectstyle.org>.
This is correct in general, but there's no hard rule on overriding (and we didn't mark these methods as "final"). A user may override those methods as long as he doesn't change their underlying behavior, so that Cayenne still functions correctly. E.g. a user may override them to trace access to specific properties, etc.

Andrus

On Feb 1, 2011, at 3:13 AM, Andrew Lindesay wrote:

> Hi Andrus;
> 
> Maybe the following two method comments may help other people understand what these methods are for...
> 
> ---
> 
> 1) readProperty
> 
> <p>
> This method exists for the benefit of the framework.  It will allow properties of the data object to be read.  This method is not intended to be overridden to provide additional functionality.  Some processing such as faulting may occur in addition to the data being returned.  If there is no value for a property then <code>null</code> will be returned.  Null will also be returned in cases where the a property is requested which is not modelled.
> </p>
> 
> ---
> 
> 2) readPropertyDirectly
> 
> <p>
> This method exists for the benefit of the framework.  It will allow properties of the data object to be read.  This method is not intended to be overridden to provide additional functionality.  Additional processing such as faulting will not occur as part of retrieving this property.  If there is no value for a property then <code>null</code> will be returned.  Null will also be returned in cases where the a property is requested which is not modelled.
> </p>
> 
> ---
> 
> Is that about right?
> 
> It is a bit of a shame that I want to implement "readProperty" and this is already taken by the framework!
> 
> cheers.
> 
>> Yeah, probably need to think about it. At the same time it is great when new extensions are created on top of Cayenne "platform", so if you implement an open source key-value-coding extension package solving specific problems, definitely mention it to the community.
> 
> -- 
> Andrew Lindesay
> www.silvereye.co.nz
> 


Re: Read Property Behaviour (CAY-1512)

Posted by Andrew Lindesay <ap...@lindesay.co.nz>.
Hi Andrus;

Maybe the following two method comments may help other people understand 
what these methods are for...

---

1) readProperty

<p>
This method exists for the benefit of the framework.  It will allow 
properties of the data object to be read.  This method is not intended 
to be overridden to provide additional functionality.  Some processing 
such as faulting may occur in addition to the data being returned.  If 
there is no value for a property then <code>null</code> will be 
returned.  Null will also be returned in cases where the a property is 
requested which is not modelled.
</p>

---

2) readPropertyDirectly

<p>
This method exists for the benefit of the framework.  It will allow 
properties of the data object to be read.  This method is not intended 
to be overridden to provide additional functionality.  Additional 
processing such as faulting will not occur as part of retrieving this 
property.  If there is no value for a property then <code>null</code> 
will be returned.  Null will also be returned in cases where the a 
property is requested which is not modelled.
</p>

---

Is that about right?

It is a bit of a shame that I want to implement "readProperty" and this 
is already taken by the framework!

cheers.

> Yeah, probably need to think about it. At the same time it is great when new extensions are created on top of Cayenne "platform", so if you implement an open source key-value-coding extension package solving specific problems, definitely mention it to the community.

-- 
Andrew Lindesay
www.silvereye.co.nz

Re: Read Property Behaviour (CAY-1512)

Posted by Andrus Adamchik <an...@objectstyle.org>.
Yeah, probably need to think about it. At the same time it is great when new extensions are created on top of Cayenne "platform", so if you implement an open source key-value-coding extension package solving specific problems, definitely mention it to the community.

Cheers,
Andrus

On Jan 31, 2011, at 3:22 AM, Andrew Lindesay wrote:
> Hi Andrus;
> 
> Thanks for getting back to me on this one.  Your comments do make sense and I think that in order to maintain focus on the "persistence framework" and maintain consistency, it may be best to remove "readNestedProperty" on CDO.
> 
> cheers.
> 
> (Andrus)
>> Sorry for delayed reply.
>> 
>> The current set of accessors 'readProperty'/'readPropertyDirectly' exists for the benefit of the framework. 'readNestedProperty' is in a different category - it is a utility method and is never used by Cayenne internally (not counting unit tests). FWIW, I'd be willing to deprecate 'CDO.readNestedProperty' and just keep its static version in the utility class. So an inconsistency you pointed to - 'readProperty' being limited to mapped properties, while 'readNestedProperty' being a mix of mapped and unmapped properties, to me is purely a *naming* inconsistency.
>> 
>> With that in mind us not having the suggested extra methods in Cayenne shouldn't prevent the customizations that you have in mind ... I think (?) You can always create a custom common superclass with a custom path navigation strategy, ignoring 'readNestedProperty' if it gets in the way (MyDataObject extends CayenneDataObject), but I am not convinced Cayenne should be the place for this code. It is a persistence framework, and staying focused on persistence is important IMO.
>> 
>> We had a discussion in the context of 'cayenne-lifecyce' recently on what should be in Cayenne core, and what is an "extension". I think here we are down to this choice also.
>> 
>> Let me know if I am still missing the point of your suggestion.
> 
> (Andrew)
>>> I've been playing around with trying to override some behaviours in the area of "read property" on the data objects, but I think I have come to the conclusion that the way it is rigged-up makes this a little difficult.  I'd like to suggest a change (which is probably more appropriate for 3.1 owing to it being a non-trivial change in behaviour) and I would be interested in any feedback.  Here is the text of the ticket...
>>> 
>>> ---
>>> 
>>> There is an issue that a data object (DO) uses the "readProperty()" method in its accessors such as "getStartTimestamp()"/"getArtist()" etc... The "readNestedProperty()" does some extra things like using reflection to get at non-modelled accessors, but "readProperty()" does not.  This is an inconsistency.
>>> 
>>> Simply adding the additional reflection to "readProperty()" is not a good idea because in the case where an object is not yet related to the model, an infinite loop can result.  Particularly in the case where a data object is not yet added to an object context, the logical condition around stopping this infinite loop is not able to be identified.
>>> 
>>> My suggestion is to add a protected "readPropertyStored()" which will be used by the accessors such as "getStartTimestamp()"/"getArtist()".  This method will ~not~ use reflection, but "readProperty()" will do the additional reflection if necessary.  The "readPropertyStored()" will continue to invoke "readPropertyDirectly()".
>>> 
>>> In addition, the "extra reflection" from "readProperty()" would be serviced through two additional methods on the data object;
>>> 
>>>   readPropertyDerived(..)
>>> 
>>> For the case of the "readNestedProperty(..)" the use of reflection into an object which is ~not~ a data object will be serviced through;
>>> 
>>>   readNestedPropertyFromNonDataObject(..)
>>> 	
>>> Together these changes will allow for consistenecy in the 'read property' behaviour and will also allow third parties to more easily extend Cayenne's 'read property' behaviors in order to support more sophisticated 'read property' behaviour.
>>> 
>>> This is a change in behavior and generated DAO classes would need to be modified to use 'readPropertyStored()' instead of 'readProperty()'.
> 
> -- 
> Andrew Lindesay
> www.silvereye.co.nz
> 


Re: Read Property Behaviour (CAY-1512)

Posted by Andrew Lindesay <ap...@lindesay.co.nz>.
Hi Andrus;

Thanks for getting back to me on this one.  Your comments do make sense 
and I think that in order to maintain focus on the "persistence 
framework" and maintain consistency, it may be best to remove 
"readNestedProperty" on CDO.

cheers.

(Andrus)
> Sorry for delayed reply.
>
> The current set of accessors 'readProperty'/'readPropertyDirectly' exists for the benefit of the framework. 'readNestedProperty' is in a different category - it is a utility method and is never used by Cayenne internally (not counting unit tests). FWIW, I'd be willing to deprecate 'CDO.readNestedProperty' and just keep its static version in the utility class. So an inconsistency you pointed to - 'readProperty' being limited to mapped properties, while 'readNestedProperty' being a mix of mapped and unmapped properties, to me is purely a *naming* inconsistency.
>
> With that in mind us not having the suggested extra methods in Cayenne shouldn't prevent the customizations that you have in mind ... I think (?) You can always create a custom common superclass with a custom path navigation strategy, ignoring 'readNestedProperty' if it gets in the way (MyDataObject extends CayenneDataObject), but I am not convinced Cayenne should be the place for this code. It is a persistence framework, and staying focused on persistence is important IMO.
>
> We had a discussion in the context of 'cayenne-lifecyce' recently on what should be in Cayenne core, and what is an "extension". I think here we are down to this choice also.
>
> Let me know if I am still missing the point of your suggestion.

(Andrew)
>> I've been playing around with trying to override some behaviours in the area of "read property" on the data objects, but I think I have come to the conclusion that the way it is rigged-up makes this a little difficult.  I'd like to suggest a change (which is probably more appropriate for 3.1 owing to it being a non-trivial change in behaviour) and I would be interested in any feedback.  Here is the text of the ticket...
>>
>> ---
>>
>> There is an issue that a data object (DO) uses the "readProperty()" method in its accessors such as "getStartTimestamp()"/"getArtist()" etc... The "readNestedProperty()" does some extra things like using reflection to get at non-modelled accessors, but "readProperty()" does not.  This is an inconsistency.
>>
>> Simply adding the additional reflection to "readProperty()" is not a good idea because in the case where an object is not yet related to the model, an infinite loop can result.  Particularly in the case where a data object is not yet added to an object context, the logical condition around stopping this infinite loop is not able to be identified.
>>
>> My suggestion is to add a protected "readPropertyStored()" which will be used by the accessors such as "getStartTimestamp()"/"getArtist()".  This method will ~not~ use reflection, but "readProperty()" will do the additional reflection if necessary.  The "readPropertyStored()" will continue to invoke "readPropertyDirectly()".
>>
>> In addition, the "extra reflection" from "readProperty()" would be serviced through two additional methods on the data object;
>>
>>    readPropertyDerived(..)
>>
>> For the case of the "readNestedProperty(..)" the use of reflection into an object which is ~not~ a data object will be serviced through;
>>
>>    readNestedPropertyFromNonDataObject(..)
>> 	
>> Together these changes will allow for consistenecy in the 'read property' behaviour and will also allow third parties to more easily extend Cayenne's 'read property' behaviors in order to support more sophisticated 'read property' behaviour.
>>
>> This is a change in behavior and generated DAO classes would need to be modified to use 'readPropertyStored()' instead of 'readProperty()'.

-- 
Andrew Lindesay
www.silvereye.co.nz

Re: Read Property Behaviour (CAY-1512)

Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi Andrew,

Sorry for delayed reply.

The current set of accessors 'readProperty'/'readPropertyDirectly' exists for the benefit of the framework. 'readNestedProperty' is in a different category - it is a utility method and is never used by Cayenne internally (not counting unit tests). FWIW, I'd be willing to deprecate 'CDO.readNestedProperty' and just keep its static version in the utility class. So an inconsistency you pointed to - 'readProperty' being limited to mapped properties, while 'readNestedProperty' being a mix of mapped and unmapped properties, to me is purely a *naming* inconsistency. 

With that in mind us not having the suggested extra methods in Cayenne shouldn't prevent the customizations that you have in mind ... I think (?) You can always create a custom common superclass with a custom path navigation strategy, ignoring 'readNestedProperty' if it gets in the way (MyDataObject extends CayenneDataObject), but I am not convinced Cayenne should be the place for this code. It is a persistence framework, and staying focused on persistence is important IMO.

We had a discussion in the context of 'cayenne-lifecyce' recently on what should be in Cayenne core, and what is an "extension". I think here we are down to this choice also.

Let me know if I am still missing the point of your suggestion.

Andrus


On Nov 17, 2010, at 1:12 PM, Andrew Lindesay wrote:

> Hello;
> 
> I've been playing around with trying to override some behaviours in the area of "read property" on the data objects, but I think I have come to the conclusion that the way it is rigged-up makes this a little difficult.  I'd like to suggest a change (which is probably more appropriate for 3.1 owing to it being a non-trivial change in behaviour) and I would be interested in any feedback.  Here is the text of the ticket...
> 
> ---
> 
> There is an issue that a data object (DO) uses the "readProperty()" method in its accessors such as "getStartTimestamp()"/"getArtist()" etc... The "readNestedProperty()" does some extra things like using reflection to get at non-modelled accessors, but "readProperty()" does not.  This is an inconsistency.
> 
> Simply adding the additional reflection to "readProperty()" is not a good idea because in the case where an object is not yet related to the model, an infinite loop can result.  Particularly in the case where a data object is not yet added to an object context, the logical condition around stopping this infinite loop is not able to be identified.
> 
> My suggestion is to add a protected "readPropertyStored()" which will be used by the accessors such as "getStartTimestamp()"/"getArtist()".  This method will ~not~ use reflection, but "readProperty()" will do the additional reflection if necessary.  The "readPropertyStored()" will continue to invoke "readPropertyDirectly()".
> 
> In addition, the "extra reflection" from "readProperty()" would be serviced through two additional methods on the data object;
> 
>   readPropertyDerived(..)
> 
> For the case of the "readNestedProperty(..)" the use of reflection into an object which is ~not~ a data object will be serviced through;
> 
>   readNestedPropertyFromNonDataObject(..)
> 	
> Together these changes will allow for consistenecy in the 'read property' behaviour and will also allow third parties to more easily extend Cayenne's 'read property' behaviors in order to support more sophisticated 'read property' behaviour.
> 
> This is a change in behavior and generated DAO classes would need to be modified to use 'readPropertyStored()' instead of 'readProperty()'.
> 
> ---
> 
> cheers.
> 
> -- 
> Andrew Lindesay
> www.silvereye.co.nz
>