Hibernate / JPA, hashCode () and Eclipse entities in Hibernate / JPA often have a synthetic (technical) primary key, which is implemented in the following example as
Long id
. If There are no additional technical key candidates, you have the
hashCode () method
for Hibernate / JPA to implement so that it works exclusively with this id. (There are at
hibernate.org a long discussion on this issue because "officially" proposed variation, "semi-unique" fields to use in practice often makes more problems than the ID variant.)
This one
hashCode ()
(equals and that the obligatory accompanying
()
) do not write again and again by hand, Eclipse offers over
Source> Generate hashCode () and equals () the possibility that the two to generate methods with selectable attributes. An example entity might look like this: @ Entity
public class Record {@ Id @
GeneratedValue
private Long id;
/ / other fields, getters, setters, equals (), etc. ...
/ ** *
generated from Eclipse 3.5.
* / @ Override
public int hashCode () {final int prime = 31
;
int result = 1;
result = prime * result +
((id == null) 0 : id?. hashCode ());
return result;}
}
in itself returns the hash value calculation using primes a good spread, and attends the automatically generated code and that may be the Id
zero - that is not stored in the database (persisted) objects.
Now we test this entity class:
@ Test public void
testAddToHashSet () {
set = new HashSet \u0026lt;Datensatz> quantitative \u0026lt;Datensatz> ();
record ds1 = new Record ();
record ds2 = new Record ();
assertTrue ("Quantity should be empty," menge.isEmpty ());
menge.add (ds1);
assertTrue ("Quantity should have an element "
menge.size () == 1);
/ / ok
menge.add (ds2);
assertTrue (" Quantity should have two elements, "
menge.size () == 2);?!
/ / still first .. Ups
}
Whenever one associations in the object model built before the records are stored (eg in case of unit tests as in the example above), occurs The above scenario. We have two objects that both have no Id (
= null
). But there are still two non-identical objects in separate memory areas corresponding to the persistence of two records with different generating primary keys (IDs) would. Unfortunately, the HashSet remember only one of the two objects - and the persistence of an association Sun would lose one of the objects!
An adaptation of the generated
hashCode ()
method is very simple. Place at a non-existing ID number
to use 0
for the hash calculation, we take the hash value of the property, which is different for non-identical objects in most cases:
@ Override
public int hashCode () {
final int prime = 31;
int result = 1;
result = prime * result +
((id == null) ? super.hashCode () : id.hashCode ());
return result;}
A similar implementation I've been using for years without problems, so I think this is the most viable option for a flat rate. In some cases, of course, more specific implementations may be more appropriate.