Harnessing hashCode as JAXB @XmlID in order to use it with @XmlIDREF

I have a class Fighter in a software for planning boxing events. I implemented its hashCode() and equals() since I collect them in various data structures in many places.

Now I want to persist specific planned boxing events which themselves contain the same Fighters in different lists. I am using JAXB for this purpose.

In order not to have duplication in the XML nodes I made use of @XmlID and @XmlIDREF such that only once the whole Fighter data is stored – but referenced in other places. The code for the id is simple and it works as expected:

@XmlID
@XmlAttribute
public String getId() {
return Integer.toString(hashCode());
}


(I was also searching for an auto-mechanism to generate those ids by JAXB but could not find anything which would be simpler as the solution above. Please tell me, if there is such a solution!)

The hashCode method looks as follows:

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result =
prime * result + ((firstNameProperty == null) ? 0 : firstNameProperty.get().hashCode());
result = prime * result + ((lastNameProperty == null) ? 0 : lastNameProperty.get().hashCode());
result = prime * result + ((genderProperty == null) ? 0 : genderProperty.get().hashCode());
result = prime * result + ((birthdayProperty == null) ? 0 : birthdayProperty.get().hashCode());
result = prime * result + ((clubProperty == null) ? 0 : clubProperty.get().hashCode());
long temp;
temp = Double.doubleToLongBits((weightProperty == null) ? 0 : weightProperty.get());
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((winsProperty == null) ? 0 : winsProperty.get());
result = prime * result + ((lossesProperty == null) ? 0 : lossesProperty.get());
result = prime * result + ((drawsProperty == null) ? 0 : drawsProperty.get());
return result;
}


And the class member variables which are used here:

private StringProperty firstNameProperty;
private StringProperty lastNameProperty;
private ObjectProperty<Gender> genderProperty;
private StringProperty clubProperty;
private ObjectProperty<LocalDate> birthdayProperty;
private DoubleProperty weightProperty;
private IntegerProperty winsProperty;
private IntegerProperty lossesProperty;
private IntegerProperty drawsProperty;


My rationale was that hashCode() would give me a unique id for every fighter and is already there.

What do you think about that? Are there any drawbacks I just don't see? Is it common to do it this way? Is there a far better solution?

Thanks for including the hashCode() method. As I suspected, the purpose of the hashCode method is to fulfil the equals/hashCode contract, and is not suitable for being an ID. For example, by changing the number of wins, you change the hashCode, and by proxy you change the player's ID.
• Thanks for your answer! Regarding a externally managed ID: The thing is, that there is none and it is also not needed per se. I only need the ID in order to be able to use the @XmlIDREF and do not have to duplicate my XML nodes, so I only need it to be consistent within my XML file but nothing more. But I see your point and I think I will take sth. like a timestamp on creation time then ... – philonous Aug 25 '15 at 15:30
• In that case, consider a UUID: randomUUID() – rolfl Aug 25 '15 at 15:33
• In case one wants to have a schema validation the id generated from randomUUID() should be prefixed with a string that allows the id to be a "NCName" as for instance "id_". More information on this can be found e.g. here. – philonous Sep 3 '15 at 11:13