Well, in some respects I agree, because this is not production code. If
you want production code from me, you hire me ;-)
Firstly, throwing ClassCastExceptions in the equals method is valid
since Java 1.0; it also provides me with a quick way to trap an
exceptional, unwanted situation. In this case, I don't just expect
ClassCastExceptions to be thrown; I ::rely:: on it, for clearer error
detection purposes. With this code, if I compare an AlbumTrackBeanPK to
a Timestamp (completely different purposes), the result is false, which
violates the business rules of my application. I've always liked the
fact that Java is strongly typed, because it makes Compiletime/Runtime
Errors/Exceptions more descriptive and thus, more easy to correct; your
example turns my Java class into a JavaScript one. Thanks, but no
thanks(no offense intended). See, JavaScript is less profitable for me
;-). On the same line, if this class is compared to a null value, a
NullPointerException might be thrown. This breaks the contract of the
equals() method (defined in java.lang.Object.equals() ). However, for
the same reasons stated above, I prefer a NullPointerException to be
thrown.
Secondly, this code was generated by an IDE. A great IDE, Pramati Studio
3.0. It'll suit most situations. Not all of them. It's just a
Wizard-Generated code. I'm sure EJBGen generated code is suitable for
::most:: situations, but you, being a intelligent, experienced developer
don't claim it'll suit all situations, right? Again, that's why I keep
on getting hired to code. On this line, I agree that the CRC is being
calculated with more information than what is actually meaningful on my
business domain(the field values, since a PK class is mostly a struct,
for the EJB/EJB-client developer point of view). The only problem I see
is regarding the hashCode implementation, is that it may/may not comply
to the hashCode contract, depending on the AppServer implementation(a
new version of the class with the same fields might produce a different
hashCode). I think this possibility should be of concern for EJB
Server/Container producers, not developers.
Thirdly, the sentence:
if (other.hashCode() != hashCode()) return false;
makes a costly calculation being done more often than it should be,
agravated by the fact that it may already be a non optimized call.
At last, these sentences won't work(not that it matters much):
1)
TrackBeanPK other2 = (TrackBeanPK) other;
There's no TrackBeanPK. The PK is java.lang.Long.
2)
return this.albumID.equals(other2.albumID) &&
this.trackId.equals(other2.trackId);
albumId & trackId are not objects, they are primitives of the 'long'
type.
To further enlighten the example I posted, this is the PK for a CMP EB,
for a linking the Album and Track CMP EBs. All the fields in AlbumTrack
are part of the PK. In my business solution domain, comparing this class
to any other class makes absolutely no sense at this time and with these
business requirements. A
Anyhow, I think the point of what a PK-class should look like went thru.
Finally, I'd like to thank you for your valuable, witty and insightful
feedback. I hope every other mail exchanged here pursues the purpose of
strengthening the EJB community. Most of the points noted here in which
I disagree are based on what I've found thru experience to be good
coding practices. They are only ::my:: preferences. Perhaps I'm wrong
and you know better. If so, hopefully, as I aquire more experience, I'll
change my preferences accordingly.
My 2c,
Juan Pablo Lorandi
Chief Software Architect
Code Foundry Ltd.
[EMAIL PROTECTED]
Barberstown, Straffan, Co. Kildare, Ireland.
Tel: +353-1-6012050 Fax: +353-1-6012051
Mobile: +353-86-2157900
www.codefoundry.com
> -----Original Message-----
> From: Cedric Beust [mailto:[EMAIL PROTECTED]]
> Sent: Monday, June 24, 2002 2:22 PM
> To: 'Juan Pablo Lorandi'; [EMAIL PROTECTED]
> Subject: Primary key (was RE: Need some examples)
>
>
> > -----Original Message-----
> > From: A mailing list for Enterprise JavaBeans development
> > [mailto:[EMAIL PROTECTED]] On Behalf Of Juan Pablo Lorandi
>
> > public boolean equals(Object obj)
> > {
> > AlbumTrackBeanPK pkObj=(AlbumTrackBeanPK)obj;
> > return (albumId==(pkObj.albumId) &&
> > trackId==(pkObj.trackId) );
> > }
>
> This is a dangerous implementation that can throw
> ClassCastException. Here is a safer one:
>
> public boolean equals(Object other) {
> if (other == this) return true;
> if (null == other) return false;
> if (other.hashCode() != hashCode()) return false;
> try {
> TrackBeanPK other2 = (TrackBeanPK) other;
> return this.albumID.equals(other2.albumID) &&
> this.trackId.equals(other2.trackId);
> }
> catch(ClassCastException ex) {
> return false;
> }
> }
>
> Note that this implementation is optimized in several ways:
>
> - Check for obvious cases first
> - Assume that in most cases, the two objects being compared
> will be of the same class
>
> > public int hashCode()
> > {
> > try
> > {
> > long crcKey = -1;
> > java.io.ByteArrayOutputStream bos = new
> > java.io.ByteArrayOutputStream();
> > java.io.ObjectOutputStream oos = new
> > java.io.ObjectOutputStream(bos);
> > oos.writeObject(this);
> > oos.flush();
> > java.util.zip.Adler32 adl32 = new
> java.util.zip.Adler32();
> > adl32.update(bos.toByteArray());
> > crcKey = adl32.getValue();
> > return (int)(crcKey ^ (crcKey >> 32));
> > } catch (java.io.IOException ioEx)
> > {
> > return -1;
> > }
> >
> > }
> > }
>
> Also, note that using ObjectOutputStream for hashcode() might
> be serializing more than is needed (e.g. FatKey pattern).
>
> --
> C�dric
>
==========================================================================To
unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".