Thread:
 Persist the hashCode, remove the need for UUIDs (s... 
 simon_t   01 Nov 2006, 11:52 

Comment
Prev. thread 
 Next thread
 
Prev. posting 
 Next posting
From: simon_t (01 Nov 2006, 11:52) Replies: 0, Views: 23782
Subject: Persist the hashCode, remove the need for UUIDs (single...
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.
Prev. thread 
 Next thread
 
Prev. posting 
 Next posting
© Copyright 2006, Red Hat Middleware, LLC. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc. [Privacy Policy]