You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by "Gentry, Michael (Contractor)" <mi...@fanniemae.com> on 2006/06/21 17:58:07 UTC

Add getHashCode() to CayenneDataObject?

Would it make sense to add:

public int getHashCode()
{
  return getObjectId().hashCode();
}

To CayenneDataObject.java?  The primary reason is to better support
Tapestry.  In T4, the @For component can take a keyExpression (which is
parsed by OGNL) which should return the primary key, which gets placed
in the HTML page (this is used due to stale link exceptions).  I don't
want to expose primary keys in the HTML, though, and using
"objectId.hashCode" doesn't work as an OGNL expression since hashCode()
!= getHashCode().  If the above method were added, "hashCode" would work
as the expression.

Any thoughts on this?  Or is there another way to get a unique value for
an object that doesn't expose the entity/keys?  If only Java let me get
the pointer (I miss &).

Thanks,

/dev/mrg

RE: Add getHashCode() to CayenneDataObject?

Posted by "Gentry, Michael (Contractor)" <mi...@fanniemae.com>.
Already have one.  I've added it for testing now.  Just thought it might
could be useful to others down the road, too.  (for convenience)

Thanks,

/dev/mrg


-----Original Message-----
From: Andrus Adamchik [mailto:andrus@objectstyle.org] 
Sent: Wednesday, June 21, 2006 12:56 PM
To: cayenne-dev@incubator.apache.org
Subject: Re: Add getHashCode() to CayenneDataObject?



On Jun 21, 2006, at 8:53 PM, Gentry, Michael ((Contractor)) wrote:

> So, would it make more sense to add a getHashCode() (which is just an
> OGNL friendly cover method) to CDO or to customize my templates?  :-)

I suggest you use a common superclass for all your DO's (DataMap ->  
Custom Superclass) instead of putting it in Cayenne or the template.

Andrus


Re: Add getHashCode() to CayenneDataObject?

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 21, 2006, at 8:53 PM, Gentry, Michael ((Contractor)) wrote:

> So, would it make more sense to add a getHashCode() (which is just an
> OGNL friendly cover method) to CDO or to customize my templates?  :-)

I suggest you use a common superclass for all your DO's (DataMap ->  
Custom Superclass) instead of putting it in Cayenne or the template.

Andrus


RE: Add getHashCode() to CayenneDataObject?

Posted by "Gentry, Michael (Contractor)" <mi...@fanniemae.com>.
Well, wasn't trying to turn this into a Tapestry or OGNL thing.  After
all, any web framework could require a unique ID of some kind and you
might not want to expose the PK.

As for keyExpression, I think it is a little bit different than a normal
OGNL since Tapestry seems to be gluing it together.  When I had
"hashCode" in the expression, I got an OGNL exception because it
couldn't find the method.

I think I'll stick with my getHashCode() wrapper right now.  My most
complex application worked using it and it is generating nice bogus
numbers for me.  :-)

Thanks!

/dev/mrg


-----Original Message-----
From: Kevin Menard [mailto:kmenard@servprise.com] 
Sent: Wednesday, June 21, 2006 2:35 PM
To: cayenne-dev@incubator.apache.org
Subject: Re: Add getHashCode() to CayenneDataObject?


On Wed, 21 Jun 2006 14:15:29 -0400, Gentry, Michael (Contractor)  
<mi...@fanniemae.com> wrote:

> The @For component can look something like this:
>
> <span jwcid="@For" source="ognl:lenders" value="ognl:currentLender"
> keyExpression="objectId">

I'm not familiar with keyExpression, but I think the handling of ognl is

uniform throughout Tapestry.

> If you aren't familiar with Tapestry, this means to loop over
> getLenders().  Each iteration over the collection sets the value with
> setCurrentLender(aLender).  And the keyExpression becomes
> getCurrentLender().getObjectId().  This works, but it serializes the
> ObjectId for each row to the HTML.  When I used "objectId.hashCode" it
> was trying getCurrentLender().getObjectId().getHashCode(), which
failed.
> Of course, that would have the problem mentioned earlier (with nulls).

Well, I have some example method calls here.  I know the first one will

make you cringe, but I'm not concerned with the PK being exposed in this

case (read-only entries):

<a href="#" jwcid="@ProductLink"  
parameters="ognl:@org.objectstyle.cayenne.DataObjectUtils@intPKForObject
(product)">

and:

<img alt="product image" jwcid="productImage@Image"  
image="ognl:product.getStoreImage(servletContext, webRequest,  
requestCycle)"/>

Note the method arguments are exposed page properties.

So, I see no real reason that you can't call whatever method you'd like.

Off the cuff, it would seem that "objectId.hashCode()" would work.

-- 
Kevin

Re: Add getHashCode() to CayenneDataObject?

Posted by Kevin Menard <km...@servprise.com>.
On Wed, 21 Jun 2006 14:15:29 -0400, Gentry, Michael (Contractor)  
<mi...@fanniemae.com> wrote:

> The @For component can look something like this:
>
> <span jwcid="@For" source="ognl:lenders" value="ognl:currentLender"
> keyExpression="objectId">

I'm not familiar with keyExpression, but I think the handling of ognl is  
uniform throughout Tapestry.

> If you aren't familiar with Tapestry, this means to loop over
> getLenders().  Each iteration over the collection sets the value with
> setCurrentLender(aLender).  And the keyExpression becomes
> getCurrentLender().getObjectId().  This works, but it serializes the
> ObjectId for each row to the HTML.  When I used "objectId.hashCode" it
> was trying getCurrentLender().getObjectId().getHashCode(), which failed.
> Of course, that would have the problem mentioned earlier (with nulls).

Well, I have some example method calls here.  I know the first one will  
make you cringe, but I'm not concerned with the PK being exposed in this  
case (read-only entries):

<a href="#" jwcid="@ProductLink"  
parameters="ognl:@org.objectstyle.cayenne.DataObjectUtils@intPKForObject(product)">

and:

<img alt="product image" jwcid="productImage@Image"  
image="ognl:product.getStoreImage(servletContext, webRequest,  
requestCycle)"/>

Note the method arguments are exposed page properties.

So, I see no real reason that you can't call whatever method you'd like.   
Off the cuff, it would seem that "objectId.hashCode()" would work.

-- 
Kevin

RE: Add getHashCode() to CayenneDataObject?

Posted by "Gentry, Michael (Contractor)" <mi...@fanniemae.com>.
Well, perhaps there is a way, but maybe not with Tapestry?

The @For component can look something like this:

<span jwcid="@For" source="ognl:lenders" value="ognl:currentLender"
keyExpression="objectId">

If you aren't familiar with Tapestry, this means to loop over
getLenders().  Each iteration over the collection sets the value with
setCurrentLender(aLender).  And the keyExpression becomes
getCurrentLender().getObjectId().  This works, but it serializes the
ObjectId for each row to the HTML.  When I used "objectId.hashCode" it
was trying getCurrentLender().getObjectId().getHashCode(), which failed.
Of course, that would have the problem mentioned earlier (with nulls).

I added a getHashCode() to my base DO which just wraps hashCode() and it
seems to be working now (bigger test to follow).  I get nice obscure
keys like "P10930889" stuck in the HTML.  (using
keyExpression="hashCode")  Safe and obscure.

Thanks,

/dev/mrg


-----Original Message-----
From: Kevin Menard [mailto:kmenard@servprise.com] 
Sent: Wednesday, June 21, 2006 1:17 PM
To: cayenne-dev@incubator.apache.org
Subject: Re: Add getHashCode() to CayenneDataObject?


On Wed, 21 Jun 2006 12:53:58 -0400, Gentry, Michael (Contractor)  
<mi...@fanniemae.com> wrote:

> The System.identityHashCode() would probably work fine, but isn't
> callable by OGNL.  Come to think of it, just being able to call
> hashCode() from OGNL would be useful, too (and equivialent to
> System.identityHashCode()).

Are you sure about this?  I've called arbitrary methods from ognl
before.   
I think your problem is probably one more of order of resolution.  I
don't  
know for certain, but it may try to access bean properties first, then  
method calls, etc.

-- 
Kevin

Re: Add getHashCode() to CayenneDataObject?

Posted by Kevin Menard <km...@servprise.com>.
On Wed, 21 Jun 2006 12:53:58 -0400, Gentry, Michael (Contractor)  
<mi...@fanniemae.com> wrote:

> The System.identityHashCode() would probably work fine, but isn't
> callable by OGNL.  Come to think of it, just being able to call
> hashCode() from OGNL would be useful, too (and equivialent to
> System.identityHashCode()).

Are you sure about this?  I've called arbitrary methods from ognl before.   
I think your problem is probably one more of order of resolution.  I don't  
know for certain, but it may try to access bean properties first, then  
method calls, etc.

-- 
Kevin

RE: Add getHashCode() to CayenneDataObject?

Posted by "Gentry, Michael (Contractor)" <mi...@fanniemae.com>.
Well, I was actually wanting a "get" in the name to work with OGNL, so
it wouldn't redefine hashCode().

The System.identityHashCode() would probably work fine, but isn't
callable by OGNL.  Come to think of it, just being able to call
hashCode() from OGNL would be useful, too (and equivialent to
System.identityHashCode()).

So, would it make more sense to add a getHashCode() (which is just an
OGNL friendly cover method) to CDO or to customize my templates?  :-)

Thanks,

/dev/mrg


-----Original Message-----
From: Andrus Adamchik [mailto:andrus@objectstyle.org] 
Sent: Wednesday, June 21, 2006 12:46 PM
To: cayenne-dev@incubator.apache.org
Subject: Re: Add getHashCode() to CayenneDataObject?


I think redefining CayenneDataObject.hashCode() is a bad idea for the  
reasons that Kevin has mentioned, and also because of uniquing (two  
objects with the same OID can sit in different contexts, so logically  
they are not the same ... they can still have the same hashCode, but  
this can be confusing).

> Any thoughts on this?  Or is there another way to get a unique  
> value for
> an object that doesn't expose the entity/keys?  If only Java let me  
> get
> the pointer (I miss &).

It gives you something close to the pointer address -  
System.identityHashCode(). Of course it won't be preserved on server  
restarts and across the cluster (so do not save it in serialized  
sessions)

Andrus



On Jun 21, 2006, at 8:30 PM, Gentry, Michael ((Contractor)) wrote:

> Ah, but will two DOs of the same class with null OIDs have the same  
> hash
> code?  If so, that would be bad, too.
>
> My basic desire is to get a unique value (an int is fine, or a short
> string, etc) for every DO that does not include entity/key information
> and the value must be reproducible.  If I could just take the  
> address of
> the DO ... Hahaha.  So, I'm open to thoughts on this ...
>
> Of course, you could argue I'm just being a security nazi, too.  You
> should see people's (seasoned web developers) eyes bugger out when I
> show them how I can edit their "secure" HTML in OmniWeb, change all  
> the
> hidden form values, and post it back to their application.  They  
> thought
> that was impossible.  (Of course, you can do the same with curl, too,
> but it is more difficult.)  Never trust the client-side data.
>
> Thanks,
>
> /dev/mrg
>
>
> -----Original Message-----
> From: Kevin Menard [mailto:kmenard@servprise.com]
> Sent: Wednesday, June 21, 2006 12:11 PM
> To: cayenne-dev@incubator.apache.org
> Subject: Re: Add getHashCode() to CayenneDataObject?
>
>
> On Wed, 21 Jun 2006 11:58:07 -0400, Gentry, Michael (Contractor)
> <mi...@fanniemae.com> wrote:
>
>> Would it make sense to add:
>>
>> public int getHashCode()
>> {
>>   return getObjectId().hashCode();
>> }
>
>> Any thoughts on this?  Or is there another way to get a unique value
> for
>> an object that doesn't expose the entity/keys?  If only Java let me
> get
>> the pointer (I miss &).
>
> My only concern is expanding the code to work with DOs that aren't yet
> registered with a DC.  In that case, the OID is null, so the above  
> code
>
> breaks.  In order to not break the equals() contract though (I'm
> assuming
> you want getHashCode() to work similarly to hashCode()), you just have
> to
> be careful how you deal with null values.  In particular, two DOs
> created
>  from different classes, both with null OIDs probably shouldn't  
> have the
>
> same hash code.
>
> -- 
> Kevin
>
>


Re: Add getHashCode() to CayenneDataObject?

Posted by Andrus Adamchik <an...@objectstyle.org>.
I think redefining CayenneDataObject.hashCode() is a bad idea for the  
reasons that Kevin has mentioned, and also because of uniquing (two  
objects with the same OID can sit in different contexts, so logically  
they are not the same ... they can still have the same hashCode, but  
this can be confusing).

> Any thoughts on this?  Or is there another way to get a unique  
> value for
> an object that doesn't expose the entity/keys?  If only Java let me  
> get
> the pointer (I miss &).

It gives you something close to the pointer address -  
System.identityHashCode(). Of course it won't be preserved on server  
restarts and across the cluster (so do not save it in serialized  
sessions)

Andrus



On Jun 21, 2006, at 8:30 PM, Gentry, Michael ((Contractor)) wrote:

> Ah, but will two DOs of the same class with null OIDs have the same  
> hash
> code?  If so, that would be bad, too.
>
> My basic desire is to get a unique value (an int is fine, or a short
> string, etc) for every DO that does not include entity/key information
> and the value must be reproducible.  If I could just take the  
> address of
> the DO ... Hahaha.  So, I'm open to thoughts on this ...
>
> Of course, you could argue I'm just being a security nazi, too.  You
> should see people's (seasoned web developers) eyes bugger out when I
> show them how I can edit their "secure" HTML in OmniWeb, change all  
> the
> hidden form values, and post it back to their application.  They  
> thought
> that was impossible.  (Of course, you can do the same with curl, too,
> but it is more difficult.)  Never trust the client-side data.
>
> Thanks,
>
> /dev/mrg
>
>
> -----Original Message-----
> From: Kevin Menard [mailto:kmenard@servprise.com]
> Sent: Wednesday, June 21, 2006 12:11 PM
> To: cayenne-dev@incubator.apache.org
> Subject: Re: Add getHashCode() to CayenneDataObject?
>
>
> On Wed, 21 Jun 2006 11:58:07 -0400, Gentry, Michael (Contractor)
> <mi...@fanniemae.com> wrote:
>
>> Would it make sense to add:
>>
>> public int getHashCode()
>> {
>>   return getObjectId().hashCode();
>> }
>
>> Any thoughts on this?  Or is there another way to get a unique value
> for
>> an object that doesn't expose the entity/keys?  If only Java let me
> get
>> the pointer (I miss &).
>
> My only concern is expanding the code to work with DOs that aren't yet
> registered with a DC.  In that case, the OID is null, so the above  
> code
>
> breaks.  In order to not break the equals() contract though (I'm
> assuming
> you want getHashCode() to work similarly to hashCode()), you just have
> to
> be careful how you deal with null values.  In particular, two DOs
> created
>  from different classes, both with null OIDs probably shouldn't  
> have the
>
> same hash code.
>
> -- 
> Kevin
>
>


RE: Add getHashCode() to CayenneDataObject?

Posted by "Gentry, Michael (Contractor)" <mi...@fanniemae.com>.
Ah, but will two DOs of the same class with null OIDs have the same hash
code?  If so, that would be bad, too.

My basic desire is to get a unique value (an int is fine, or a short
string, etc) for every DO that does not include entity/key information
and the value must be reproducible.  If I could just take the address of
the DO ... Hahaha.  So, I'm open to thoughts on this ...

Of course, you could argue I'm just being a security nazi, too.  You
should see people's (seasoned web developers) eyes bugger out when I
show them how I can edit their "secure" HTML in OmniWeb, change all the
hidden form values, and post it back to their application.  They thought
that was impossible.  (Of course, you can do the same with curl, too,
but it is more difficult.)  Never trust the client-side data.

Thanks,

/dev/mrg


-----Original Message-----
From: Kevin Menard [mailto:kmenard@servprise.com] 
Sent: Wednesday, June 21, 2006 12:11 PM
To: cayenne-dev@incubator.apache.org
Subject: Re: Add getHashCode() to CayenneDataObject?


On Wed, 21 Jun 2006 11:58:07 -0400, Gentry, Michael (Contractor)  
<mi...@fanniemae.com> wrote:

> Would it make sense to add:
>
> public int getHashCode()
> {
>   return getObjectId().hashCode();
> }

> Any thoughts on this?  Or is there another way to get a unique value
for
> an object that doesn't expose the entity/keys?  If only Java let me
get
> the pointer (I miss &).

My only concern is expanding the code to work with DOs that aren't yet  
registered with a DC.  In that case, the OID is null, so the above code

breaks.  In order to not break the equals() contract though (I'm
assuming  
you want getHashCode() to work similarly to hashCode()), you just have
to  
be careful how you deal with null values.  In particular, two DOs
created  
 from different classes, both with null OIDs probably shouldn't have the

same hash code.

-- 
Kevin


Re: Add getHashCode() to CayenneDataObject?

Posted by Kevin Menard <km...@servprise.com>.
On Wed, 21 Jun 2006 11:58:07 -0400, Gentry, Michael (Contractor)  
<mi...@fanniemae.com> wrote:

> Would it make sense to add:
>
> public int getHashCode()
> {
>   return getObjectId().hashCode();
> }

> Any thoughts on this?  Or is there another way to get a unique value for
> an object that doesn't expose the entity/keys?  If only Java let me get
> the pointer (I miss &).

My only concern is expanding the code to work with DOs that aren't yet  
registered with a DC.  In that case, the OID is null, so the above code  
breaks.  In order to not break the equals() contract though (I'm assuming  
you want getHashCode() to work similarly to hashCode()), you just have to  
be careful how you deal with null values.  In particular, two DOs created  
 from different classes, both with null OIDs probably shouldn't have the  
same hash code.

-- 
Kevin