I have a proposal for applications that run on a single JVM that was inspired by the UUID solutions. There are issues with this proposal for applications spanning multiple JVMs (more on that later). I may be pointing people in the wrong direction here so if you see anything wrong with what is below please post a response. I don't see why we have to implement equals using a UUID. I can understand why we have to for hashCode but not equals. If an equals of a User object is implemented as: private Integer id; public void equal(Object object) { if (object == null) { return false; } if (!(object instanceof User)) { return false; } if (id == null) { return super.equals(object); } else { return id.equals(((User)object.id)); } } Then before a User is saved the id will be null. It will not equal any other object except itself. After saving a User the id will not be null and will equal any User object with the same id. This equals will work for the following scenario: 1. A new User object is created, call it user1 2. In a Hibernate session user1 is saved. At this point the user1 object will be assigned an id of 1. 3. In a different session the user with an id of 1 is loaded. Call the corresponding object user2 4. Using equals compare user1 to user2. They will be equal because they have the same id. So what do we do with hashCode? The issue with Hibernate and hashCodes is that when an object is saved the hashCode changes. A solution to this is to derive the hashCode before saving and to persist this value for future instances. This can be implemented as (using java 1.5): private Integer hashCode; public int hashCode() { if (hashCode == null) { // provided the super classes do not override hashCode hashCode = super.hashCode(); } return hashCode; } // expected to be mapped to a column in the database like HASH_CODE public Integer getHashCode() { return hashCode; } // expected to be mapped to a column in the database like HASH_CODE public void setHashCode(Integer hashCode) { this.hashCode = hashCode; } This implementation is similar to the UUID proposals (and in fact was inspired by them) but will take up less space in the database. Instead of 128 bits only 32 bits are used. So why will this not work on applications that span multiple JVMs? This is all theoretical because I've never worked on such an application but I think my concerns are worth mentioning. This proposal relies the fact that when an instance of an object is saved, its id is set. This does not happen if an instance of an object is created in one JVM (call it jvm1) and sent to a different JVM (call it jvm2) to be saved. Hibernate will only set the id of the instance in jvm2 not the id of the instance in jvm1. Setting of the id of the instance in jvm1 will not happen without some extra mechanism to send the id back to jvm1.