You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Kevin Menard <km...@servprise.com> on 2008/04/27 16:08:08 UTC

Client PK access

As part of the fix for CAY-574, we added a getPrimaryKeyNames() :
Collection<String> method to ObjEntity.  This did the trick and allowed
DataObjectUtils to work.  Unfortunately, it doesn't expose the PK type
information.

As some of you likely know, I'm working on Tapestry5-Cayenne integration
module with Robert Zeigler.  I'm trying to ensure the module works just as
well for an ROP client as it does for traditional Cayenne server apps.  One
of the things we need to be able to handle is the coercion of keys to and
from String values.  This implies knowledge of the key class type, which is
currently unavailable in the client.

I'm soliciting ideas on how to improve this.  Off the top of my head, I'm
thinking something like the following:

// Simple key-> value lookup.
String getPkClassName(String pkName)

// Modification of existing method to allow PK lookups.
ObjAttribute getAttribute(String name, boolean includePks)

// Rather than just have getPrimaryKeyNames(), return a mapping
// of the key name and its Java class.
Map<String, String> getPrimaryKeys()

If possible, this is something I'd like to see squeezed in for 3.0M4,
because I'd really like that module to not have to rely on 3.0-SNAPSHOT.

Thanks,
Kevin


Re: Client PK access

Posted by Michael Gentry <bl...@gmail.com>.
FWIW, I've seen Oracle automatically/silently convert numbers to
varchars before, too (999 => '999').  This works great until your
numbers start having letters in them.  :-)


On Mon, Apr 28, 2008 at 3:36 AM, Andrus Adamchik <an...@objectstyle.org> wrote:
>
>  On Apr 28, 2008, at 12:14 AM, Kevin Menard wrote:
>
>
> > Having said that, I was looking more into how DataObjectUtils handles
> String values and it looks like it handles the conversion fairly well in the
> absence of type information.  I'll have to look into it more though.  If
> that be the case, your initial reaction may have been well-founded.
> >
>
>  My suspicion without reviewing the algorithm, is that it will miss objects
> cached in memory, as it doesn't do any type conversion by itself, an an
> ObjectId "equals" method implementation depends on correct value(s) type
> (ObjectId is used as an object map key throughout Cayenne). So it will query
> the database every time, and if the DB is ok with matching numerics against
> varchars, it will produce correct results. If not - this will result in a
> server-side SQLException. Again, going from memory, I think MySQL will work,
> PostgreSQL will break. But that's worth double-checking.
>
>  Andrus
>
>

Re: Client PK access

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

If SVN is down when you are ready to commit, attach a patch to Jira -  
I'll apply it once it is back online.

Andrus

On May 2, 2008, at 6:10 PM, Kevin Menard wrote:

> I think this may be the best bet.  It affords us the most  
> flexibility in the event that someone needs some other piece of  
> metadata.
>
> If no one objects, I'll open up a JIRA and try to take care of it  
> before I leave tomorrow.  Unless it's something we want to vet out a  
> bit more before the M4 release.  I'd just hate to have the  
> integration module have a dependency on a snapshot release.
>
> -- 
> Kevin
>
> On Apr 28, 2008, at 3:49 AM, Andrus Adamchik wrote:
>
>> Extending this thought, maybe we can make ObjectIdQuery optionally  
>> perform type conversion in "getObjectId()" and  
>> "createRelacementQuery()" methods. This would still result in a  
>> cache miss on the client, but will work correctly everywhere on the  
>> server.
>>
>> ... Or maybe we go along the lines of your original suggestion and  
>> just replace
>>
>>  Collection<String> getPrimaryKeyNames();
>>
>> with
>>
>>  Collection<ObjAttribute> getPrimaryKeys();
>>
>> returning "synthetic" ObjAttributes that won't be present in the  
>> collection returned via "getAttributes()".
>>
>> Andrus
>>
>>
>> On Apr 28, 2008, at 10:36 AM, Andrus Adamchik wrote:
>>> On Apr 28, 2008, at 12:14 AM, Kevin Menard wrote:
>>>
>>>> Having said that, I was looking more into how DataObjectUtils  
>>>> handles String values and it looks like it handles the conversion  
>>>> fairly well in the absence of type information.  I'll have to  
>>>> look into it more though.  If that be the case, your initial  
>>>> reaction may have been well-founded.
>>>
>>> My suspicion without reviewing the algorithm, is that it will miss  
>>> objects cached in memory, as it doesn't do any type conversion by  
>>> itself, an an ObjectId "equals" method implementation depends on  
>>> correct value(s) type (ObjectId is used as an object map key  
>>> throughout Cayenne). So it will query the database every time, and  
>>> if the DB is ok with matching numerics against varchars, it will  
>>> produce correct results. If not - this will result in a server- 
>>> side SQLException. Again, going from memory, I think MySQL will  
>>> work, PostgreSQL will break. But that's worth double-checking.
>>>
>>> Andrus
>>>
>>>
>>
>
>


Re: Client PK access

Posted by Kevin Menard <km...@servprise.com>.
I think this may be the best bet.  It affords us the most flexibility  
in the event that someone needs some other piece of metadata.

If no one objects, I'll open up a JIRA and try to take care of it  
before I leave tomorrow.  Unless it's something we want to vet out a  
bit more before the M4 release.  I'd just hate to have the integration  
module have a dependency on a snapshot release.

-- 
Kevin

On Apr 28, 2008, at 3:49 AM, Andrus Adamchik wrote:

> Extending this thought, maybe we can make ObjectIdQuery optionally  
> perform type conversion in "getObjectId()" and  
> "createRelacementQuery()" methods. This would still result in a  
> cache miss on the client, but will work correctly everywhere on the  
> server.
>
> ... Or maybe we go along the lines of your original suggestion and  
> just replace
>
>   Collection<String> getPrimaryKeyNames();
>
> with
>
>   Collection<ObjAttribute> getPrimaryKeys();
>
> returning "synthetic" ObjAttributes that won't be present in the  
> collection returned via "getAttributes()".
>
> Andrus
>
>
> On Apr 28, 2008, at 10:36 AM, Andrus Adamchik wrote:
>> On Apr 28, 2008, at 12:14 AM, Kevin Menard wrote:
>>
>>> Having said that, I was looking more into how DataObjectUtils  
>>> handles String values and it looks like it handles the conversion  
>>> fairly well in the absence of type information.  I'll have to look  
>>> into it more though.  If that be the case, your initial reaction  
>>> may have been well-founded.
>>
>> My suspicion without reviewing the algorithm, is that it will miss  
>> objects cached in memory, as it doesn't do any type conversion by  
>> itself, an an ObjectId "equals" method implementation depends on  
>> correct value(s) type (ObjectId is used as an object map key  
>> throughout Cayenne). So it will query the database every time, and  
>> if the DB is ok with matching numerics against varchars, it will  
>> produce correct results. If not - this will result in a server-side  
>> SQLException. Again, going from memory, I think MySQL will work,  
>> PostgreSQL will break. But that's worth double-checking.
>>
>> Andrus
>>
>>
>


Re: Client PK access

Posted by Andrus Adamchik <an...@objectstyle.org>.
Extending this thought, maybe we can make ObjectIdQuery optionally  
perform type conversion in "getObjectId()" and  
"createRelacementQuery()" methods. This would still result in a cache  
miss on the client, but will work correctly everywhere on the server.

... Or maybe we go along the lines of your original suggestion and  
just replace

    Collection<String> getPrimaryKeyNames();

with

    Collection<ObjAttribute> getPrimaryKeys();

returning "synthetic" ObjAttributes that won't be present in the  
collection returned via "getAttributes()".

Andrus


On Apr 28, 2008, at 10:36 AM, Andrus Adamchik wrote:
> On Apr 28, 2008, at 12:14 AM, Kevin Menard wrote:
>
>> Having said that, I was looking more into how DataObjectUtils  
>> handles String values and it looks like it handles the conversion  
>> fairly well in the absence of type information.  I'll have to look  
>> into it more though.  If that be the case, your initial reaction  
>> may have been well-founded.
>
> My suspicion without reviewing the algorithm, is that it will miss  
> objects cached in memory, as it doesn't do any type conversion by  
> itself, an an ObjectId "equals" method implementation depends on  
> correct value(s) type (ObjectId is used as an object map key  
> throughout Cayenne). So it will query the database every time, and  
> if the DB is ok with matching numerics against varchars, it will  
> produce correct results. If not - this will result in a server-side  
> SQLException. Again, going from memory, I think MySQL will work,  
> PostgreSQL will break. But that's worth double-checking.
>
> Andrus
>
>


Re: Client PK access

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Apr 28, 2008, at 12:14 AM, Kevin Menard wrote:

> Having said that, I was looking more into how DataObjectUtils  
> handles String values and it looks like it handles the conversion  
> fairly well in the absence of type information.  I'll have to look  
> into it more though.  If that be the case, your initial reaction may  
> have been well-founded.

My suspicion without reviewing the algorithm, is that it will miss  
objects cached in memory, as it doesn't do any type conversion by  
itself, an an ObjectId "equals" method implementation depends on  
correct value(s) type (ObjectId is used as an object map key  
throughout Cayenne). So it will query the database every time, and if  
the DB is ok with matching numerics against varchars, it will produce  
correct results. If not - this will result in a server-side  
SQLException. Again, going from memory, I think MySQL will work,  
PostgreSQL will break. But that's worth double-checking.

Andrus


Re: Client PK access

Posted by Kevin Menard <km...@servprise.com>.
On Apr 27, 2008, at 1:22 PM, Andrus Adamchik wrote:

> My initial negative reaction was based on the fact that Cayenne  
> doesn't actually have the concept of an unmapped PK *Java* type on  
> the server either. It is derived from JDBC default mapping (and  
> often interpreted differently by different drivers). So creating a  
> method on ObjEntity that would imply otherwise would be misleading.

Right.  What I'm looking for is the type used by the adapter.  I'm not  
sure using anything else would make much sense.

> Now looking up an object based on an encoded PK is indeed an  
> extremely important operation in any webapp, so we need to provide  
> some facility for generic key decoding. I wrote my own ObjectId  
> DataSqueezers for Tapestry 4 not so long ago, which did not require  
> the knowledge of an implicit Java PK type. Type information was  
> encoded in the PK string. E.g. I35 or L444. Do you think you can use  
> the same approach? Does it cover all scenarios?

This would certainly be doable and is indeed how things have been done  
with T4.  We're striving for prettier URLs as it were.  A given URL  
will already map to an entity and based on position, we'll know what  
the PK value is.  So, the inclusion of PK type data just makes the URL  
uglier and wouldn't be necessary if the entity could tell us what type  
to use for the PK.

Having said that, I was looking more into how DataObjectUtils handles  
String values and it looks like it handles the conversion fairly well  
in the absence of type information.  I'll have to look into it more  
though.  If that be the case, your initial reaction may have been well- 
founded.

-- 
Kevin


>
>
> Andrus
>
>
>
> On Apr 27, 2008, at 6:08 PM, Andrus Adamchik wrote:
>
>> I'd say if you care about such details as PK type, you should map  
>> it as a meaningful ObjAttribute. I am not convinced that we need to  
>> do something else here.
>>
>> Andrus
>>
>> On Apr 27, 2008, at 5:08 PM, Kevin Menard wrote:
>>
>>> As part of the fix for CAY-574, we added a getPrimaryKeyNames() :
>>> Collection<String> method to ObjEntity.  This did the trick and  
>>> allowed
>>> DataObjectUtils to work.  Unfortunately, it doesn't expose the PK  
>>> type
>>> information.
>>>
>>> As some of you likely know, I'm working on Tapestry5-Cayenne  
>>> integration
>>> module with Robert Zeigler.  I'm trying to ensure the module works  
>>> just as
>>> well for an ROP client as it does for traditional Cayenne server  
>>> apps.  One
>>> of the things we need to be able to handle is the coercion of keys  
>>> to and
>>> from String values.  This implies knowledge of the key class type,  
>>> which is
>>> currently unavailable in the client.
>>>
>>> I'm soliciting ideas on how to improve this.  Off the top of my  
>>> head, I'm
>>> thinking something like the following:
>>>
>>> // Simple key-> value lookup.
>>> String getPkClassName(String pkName)
>>>
>>> // Modification of existing method to allow PK lookups.
>>> ObjAttribute getAttribute(String name, boolean includePks)
>>>
>>> // Rather than just have getPrimaryKeyNames(), return a mapping
>>> // of the key name and its Java class.
>>> Map<String, String> getPrimaryKeys()
>>>
>>> If possible, this is something I'd like to see squeezed in for  
>>> 3.0M4,
>>> because I'd really like that module to not have to rely on 3.0- 
>>> SNAPSHOT.
>>>
>>> Thanks,
>>> Kevin


Re: Client PK access

Posted by Andrus Adamchik <an...@objectstyle.org>.
My initial negative reaction was based on the fact that Cayenne  
doesn't actually have the concept of an unmapped PK *Java* type on the  
server either. It is derived from JDBC default mapping (and often  
interpreted differently by different drivers). So creating a method on  
ObjEntity that would imply otherwise would be misleading.

Now looking up an object based on an encoded PK is indeed an extremely  
important operation in any webapp, so we need to provide some facility  
for generic key decoding. I wrote my own ObjectId DataSqueezers for  
Tapestry 4 not so long ago, which did not require the knowledge of an  
implicit Java PK type. Type information was encoded in the PK string.  
E.g. I35 or L444. Do you think you can use the same approach? Does it  
cover all scenarios?

Andrus



On Apr 27, 2008, at 6:08 PM, Andrus Adamchik wrote:

> I'd say if you care about such details as PK type, you should map it  
> as a meaningful ObjAttribute. I am not convinced that we need to do  
> something else here.
>
> Andrus
>
> On Apr 27, 2008, at 5:08 PM, Kevin Menard wrote:
>
>> As part of the fix for CAY-574, we added a getPrimaryKeyNames() :
>> Collection<String> method to ObjEntity.  This did the trick and  
>> allowed
>> DataObjectUtils to work.  Unfortunately, it doesn't expose the PK  
>> type
>> information.
>>
>> As some of you likely know, I'm working on Tapestry5-Cayenne  
>> integration
>> module with Robert Zeigler.  I'm trying to ensure the module works  
>> just as
>> well for an ROP client as it does for traditional Cayenne server  
>> apps.  One
>> of the things we need to be able to handle is the coercion of keys  
>> to and
>> from String values.  This implies knowledge of the key class type,  
>> which is
>> currently unavailable in the client.
>>
>> I'm soliciting ideas on how to improve this.  Off the top of my  
>> head, I'm
>> thinking something like the following:
>>
>> // Simple key-> value lookup.
>> String getPkClassName(String pkName)
>>
>> // Modification of existing method to allow PK lookups.
>> ObjAttribute getAttribute(String name, boolean includePks)
>>
>> // Rather than just have getPrimaryKeyNames(), return a mapping
>> // of the key name and its Java class.
>> Map<String, String> getPrimaryKeys()
>>
>> If possible, this is something I'd like to see squeezed in for 3.0M4,
>> because I'd really like that module to not have to rely on 3.0- 
>> SNAPSHOT.
>>
>> Thanks,
>> Kevin

Re: Client PK access

Posted by Andrus Adamchik <an...@objectstyle.org>.
I'd say if you care about such details as PK type, you should map it  
as a meaningful ObjAttribute. I am not convinced that we need to do  
something else here.

Andrus

On Apr 27, 2008, at 5:08 PM, Kevin Menard wrote:

> As part of the fix for CAY-574, we added a getPrimaryKeyNames() :
> Collection<String> method to ObjEntity.  This did the trick and  
> allowed
> DataObjectUtils to work.  Unfortunately, it doesn't expose the PK type
> information.
>
> As some of you likely know, I'm working on Tapestry5-Cayenne  
> integration
> module with Robert Zeigler.  I'm trying to ensure the module works  
> just as
> well for an ROP client as it does for traditional Cayenne server  
> apps.  One
> of the things we need to be able to handle is the coercion of keys  
> to and
> from String values.  This implies knowledge of the key class type,  
> which is
> currently unavailable in the client.
>
> I'm soliciting ideas on how to improve this.  Off the top of my  
> head, I'm
> thinking something like the following:
>
> // Simple key-> value lookup.
> String getPkClassName(String pkName)
>
> // Modification of existing method to allow PK lookups.
> ObjAttribute getAttribute(String name, boolean includePks)
>
> // Rather than just have getPrimaryKeyNames(), return a mapping
> // of the key name and its Java class.
> Map<String, String> getPrimaryKeys()
>
> If possible, this is something I'd like to see squeezed in for 3.0M4,
> because I'd really like that module to not have to rely on 3.0- 
> SNAPSHOT.
>
> Thanks,
> Kevin
>
>


Re: Client PK access

Posted by Michael Gentry <bl...@gmail.com>.
Thanks for the link, Kevin.  It seems Robert listened to me!  :-)

http://code.google.com/p/tapestry5-cayenne/wiki/SecuringValueEncoders

For an externally-facing application (and even some internal), it
seems pluggable encryption might be the best approach (you don't want
to include actual encryption, though).  These overly-secure types of
applications rarely care about friendly URLs, from what I've seen thus
far and many are form/POST-based.  I'll check out more later.

Thanks!


On Sun, Apr 27, 2008 at 12:03 PM, Kevin Menard <km...@servprise.com> wrote:
> Hi Michael,
>
>  We're looking to basically achieve feature parity with the Hibernate module
>  and then surpass it.  We've got some pretty good stuff going on right now.
>  The simplest way forward was to include keys in the URLs, but we intend on
>  making things more secure going forward.
>
>  If you want to get involved with discussions and what not, feel free to join
>  the group.  It's pretty low volume:
>
>  http://code.google.com/p/tapestry5-cayenne/
>
>  --
>  Kevin
>
>
>
>
>  On 4/27/08 11:50 AM, "Michael Gentry" <bl...@gmail.com> wrote:
>
>  > Hi Kevin,
>  >
>  > I'm just curious since I haven't been following Tapestry much lately
>  > (I'm in WebObjects land currently) if you are making a data squeezer
>  > (or whatever they are calling it in T5) for Cayenne?  If so, is it
>  > just going to stuff primary keys into the HTML as hidden fields or be
>  > something more elaborate?  The environments I've worked in tend to
>  > need data security and exposing the primary keys in the HTML would be
>  > a definite no-no.  You never want to give the client/end-user a chance
>  > to hack the primary key values to try gain backdoor access to the
>  > data.
>  >
>  > Thanks!
>  >
>  > /dev/mrg
>  >
>  >
>  > On Sun, Apr 27, 2008 at 10:08 AM, Kevin Menard <km...@servprise.com> wrote:
>  >> As part of the fix for CAY-574, we added a getPrimaryKeyNames() :
>  >>  Collection<String> method to ObjEntity.  This did the trick and allowed
>  >>  DataObjectUtils to work.  Unfortunately, it doesn't expose the PK type
>  >>  information.
>  >>
>  >>  As some of you likely know, I'm working on Tapestry5-Cayenne integration
>  >>  module with Robert Zeigler.  I'm trying to ensure the module works just as
>  >>  well for an ROP client as it does for traditional Cayenne server apps.  One
>  >>  of the things we need to be able to handle is the coercion of keys to and
>  >>  from String values.  This implies knowledge of the key class type, which is
>  >>  currently unavailable in the client.
>  >>
>  >>  I'm soliciting ideas on how to improve this.  Off the top of my head, I'm
>  >>  thinking something like the following:
>  >>
>  >>  // Simple key-> value lookup.
>  >>  String getPkClassName(String pkName)
>  >>
>  >>  // Modification of existing method to allow PK lookups.
>  >>  ObjAttribute getAttribute(String name, boolean includePks)
>  >>
>  >>  // Rather than just have getPrimaryKeyNames(), return a mapping
>  >>  // of the key name and its Java class.
>  >>  Map<String, String> getPrimaryKeys()
>  >>
>  >>  If possible, this is something I'd like to see squeezed in for 3.0M4,
>  >>  because I'd really like that module to not have to rely on 3.0-SNAPSHOT.
>  >>
>  >>  Thanks,
>  >>  Kevin
>  >>
>  >>
>
>

Re: Client PK access

Posted by Kevin Menard <km...@servprise.com>.
Hi Michael,

We're looking to basically achieve feature parity with the Hibernate module
and then surpass it.  We've got some pretty good stuff going on right now.
The simplest way forward was to include keys in the URLs, but we intend on
making things more secure going forward.

If you want to get involved with discussions and what not, feel free to join
the group.  It's pretty low volume:

http://code.google.com/p/tapestry5-cayenne/

-- 
Kevin


On 4/27/08 11:50 AM, "Michael Gentry" <bl...@gmail.com> wrote:

> Hi Kevin,
> 
> I'm just curious since I haven't been following Tapestry much lately
> (I'm in WebObjects land currently) if you are making a data squeezer
> (or whatever they are calling it in T5) for Cayenne?  If so, is it
> just going to stuff primary keys into the HTML as hidden fields or be
> something more elaborate?  The environments I've worked in tend to
> need data security and exposing the primary keys in the HTML would be
> a definite no-no.  You never want to give the client/end-user a chance
> to hack the primary key values to try gain backdoor access to the
> data.
> 
> Thanks!
> 
> /dev/mrg
> 
> 
> On Sun, Apr 27, 2008 at 10:08 AM, Kevin Menard <km...@servprise.com> wrote:
>> As part of the fix for CAY-574, we added a getPrimaryKeyNames() :
>>  Collection<String> method to ObjEntity.  This did the trick and allowed
>>  DataObjectUtils to work.  Unfortunately, it doesn't expose the PK type
>>  information.
>> 
>>  As some of you likely know, I'm working on Tapestry5-Cayenne integration
>>  module with Robert Zeigler.  I'm trying to ensure the module works just as
>>  well for an ROP client as it does for traditional Cayenne server apps.  One
>>  of the things we need to be able to handle is the coercion of keys to and
>>  from String values.  This implies knowledge of the key class type, which is
>>  currently unavailable in the client.
>> 
>>  I'm soliciting ideas on how to improve this.  Off the top of my head, I'm
>>  thinking something like the following:
>> 
>>  // Simple key-> value lookup.
>>  String getPkClassName(String pkName)
>> 
>>  // Modification of existing method to allow PK lookups.
>>  ObjAttribute getAttribute(String name, boolean includePks)
>> 
>>  // Rather than just have getPrimaryKeyNames(), return a mapping
>>  // of the key name and its Java class.
>>  Map<String, String> getPrimaryKeys()
>> 
>>  If possible, this is something I'd like to see squeezed in for 3.0M4,
>>  because I'd really like that module to not have to rely on 3.0-SNAPSHOT.
>> 
>>  Thanks,
>>  Kevin
>> 
>> 


Re: Client PK access

Posted by Michael Gentry <bl...@gmail.com>.
Hi Kevin,

I'm just curious since I haven't been following Tapestry much lately
(I'm in WebObjects land currently) if you are making a data squeezer
(or whatever they are calling it in T5) for Cayenne?  If so, is it
just going to stuff primary keys into the HTML as hidden fields or be
something more elaborate?  The environments I've worked in tend to
need data security and exposing the primary keys in the HTML would be
a definite no-no.  You never want to give the client/end-user a chance
to hack the primary key values to try gain backdoor access to the
data.

Thanks!

/dev/mrg


On Sun, Apr 27, 2008 at 10:08 AM, Kevin Menard <km...@servprise.com> wrote:
> As part of the fix for CAY-574, we added a getPrimaryKeyNames() :
>  Collection<String> method to ObjEntity.  This did the trick and allowed
>  DataObjectUtils to work.  Unfortunately, it doesn't expose the PK type
>  information.
>
>  As some of you likely know, I'm working on Tapestry5-Cayenne integration
>  module with Robert Zeigler.  I'm trying to ensure the module works just as
>  well for an ROP client as it does for traditional Cayenne server apps.  One
>  of the things we need to be able to handle is the coercion of keys to and
>  from String values.  This implies knowledge of the key class type, which is
>  currently unavailable in the client.
>
>  I'm soliciting ideas on how to improve this.  Off the top of my head, I'm
>  thinking something like the following:
>
>  // Simple key-> value lookup.
>  String getPkClassName(String pkName)
>
>  // Modification of existing method to allow PK lookups.
>  ObjAttribute getAttribute(String name, boolean includePks)
>
>  // Rather than just have getPrimaryKeyNames(), return a mapping
>  // of the key name and its Java class.
>  Map<String, String> getPrimaryKeys()
>
>  If possible, this is something I'd like to see squeezed in for 3.0M4,
>  because I'd really like that module to not have to rely on 3.0-SNAPSHOT.
>
>  Thanks,
>  Kevin
>
>