Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to write hasCode() & equals(0) methods in Compound Key Class

 
Jack Bush
Ranch Hand
Posts: 235
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

I am wondering how to write the hashCode() and equals() methods that is mandatory when creating composite

@IdClass. Below is the combination of primary @Id keys that I would like to make up in a compound key class:


public final class PatientKey implements java.io.Serializable
{
private String firstnameId;
private String SurnameId;
private String DateOfBirthID;
private String Sex;

public int hashCode()
{
.....
}

public boolean equals(Object otherOb)
{
......
}

......
}


The Order application in Java EE 5 Tutorial (page 841) is made up of only 2 primary keys.

Below is an example of the primary compound class key I am trying to replicate. It is the LineItemKey class that is part of the Order application from the same tutorial:


public class LineItemKey implements Serializable {
private Integer orderId;
private int itemId;

public LineItemKey() {
}

public LineItemKey(
Integer orderId,
int itemId) {
this.setOrderId(orderId);
this.setItemId(itemId);
}

public int hashCode() {
return (((this.getOrderId() == null) ? 0 : this.getOrderId()
.hashCode())
^ ((int) this.getItemId()));
}

public boolean equals(Object otherOb) {
if (this == otherOb) {
return true;
}

if (!(otherOb instanceof LineItemKey)) {
return false;
}

LineItemKey other = (LineItemKey) otherOb;

return (((this.getOrderId() == null) ? (other.getOrderId() == null)
: this.getOrderId()
.equals(other.getOrderId()))
&& (this.getItemId() == other.getItemId()));
}
.....
}

These methods are making comparison between 2 objects based on their properties. I would like to achieve the same thing in an identical compound class (@IdClass) based on at least 4 or more properties. ie firstname, surname, dob and sex.

Thanks,

Jack
 
Jack Bush
Ranch Hand
Posts: 235
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Could anyone provide some suggestion on how this could be done?

I am still at a loss on how to do this.

Thanks alot,

Jack
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34401
346
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jack,
There's nothing EJB specific about these methods. They are just normal Java equals() and hashCode() methods. Note that EqualsBuilder provides dynamic implementations so you don't have to write your own.
 
Jack Bush
Ranch Hand
Posts: 235
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jeanne,

Thanks for responding to this query.

I am wondering if you could confirm whether the equals() and hashcode() for the following PatientPK composite class is correct:


Thanks again,

Jack
 
Scott Selikoff
author
Saloon Keeper
Posts: 4014
18
Eclipse IDE Flex Google Web Toolkit
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't like the looks of "if (obj == this) return true;" inside of equals() method, it seems like a bad idea.

Other than that, this really is not an EJB issue, its more of a general java question, so I'm moving it to Java Intermediate. You should read up on equals() methods. Usually in a database environment you have a unique primary key (String, Integer, or Long) that unique determines the object.
[ May 29, 2008: Message edited by: Scott Selikoff ]
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Scott Selikoff: I don't like the looks of "if (obj == this) return true;" inside of equals() method, it seems like a bad idea.

What don't you like about that? That seems to be a pretty common idiom in equals comparisons, a shortcut that says comparing this object to itself for equality will always return true. That seems logical.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Scott]: I don't like the looks of "if (obj == this) return true;" inside of equals() method, it seems like a bad idea.

Really? Why? Seems to me that it's generally not necessary, but it can be a useful performance enhancement. You can see the same thing in the source code for java.lang.String, for example.
 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have a fundamental issue here. The object is not immutable, the hashcode value is taken from the values of the "name" fields. If someone constructs an instance, sets the names, and puts it in a HashMap, then changes the name, you will never find it in the Hash again.

This will cause subtle and evil bugs. And can lead to memory leaks.

The protoype in java.lang.Object hints that you can do this, as long as the calculation of hashCode() is changed whenever equals() would change. But I've found, the hard way, that this is dangerous.
 
Campbell Ritchie
Sheriff
Pie
Posts: 48940
60
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Scott Selikoff:
I don't like the looks of "if (obj == this) return true;"
I think Scott is worried about the return statement in the middle of the method.

try

return obj == this || (everything else);
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, that would mean he would object to almost every line as well. He only mentioned the one.
 
Bill Shirley
Ranch Hand
Posts: 457
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
(google will find you many suggestions, tips, and tricks,)


equals() and hashCode() can be used A LOT, therefore optimizing them is usually desirable.

i usually put in a quick and dirty implementation with a note to myself to optimize - getting it working is the most important part, making it work faster is secondary,

the assumption of an instance variable not being null will burn you!


hashcode does not HAVE to differentiate between different objects,
it is very unlikely that you will have two people with the same name and birthday who are of the opposite sex,

minimize

 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Bill's example shows, using sex is not a very useful thing to include in a hashCode().

In fact, using sex is rarely useful in hashCode or database indexes, It doesn't restrict the population well. Its usually more effort to calculate, maintain, etc. the field than it saves in your application. This can be worse in some domains, such as soldiers, who are nearly always male.
 
Jack Bush
Ranch Hand
Posts: 235
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

Can you confirm whether using EqualsBuilder and HashCodeBuilder below is equivalent to my own set of methods shown earlier, in addition to any alleviating unforseeing nasty surprises that you have already covered:


If so, I am happy to try it out.

Thanks,

Jack
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic