piątek, 8 kwietnia 2011

Equals, hashCode i Hibernate

Ok, to był dość długi wstęp (1, 2, 3), może czasami jak dla dzieci, ale przynajmniej wszystko jest w 1 miejscu, a składa się na meritum problemu, czyli jak powinno się implementować metody equals() i hashCode() w połączeniu z Hibernatem. Mówiąc jeszcze bardziej precyzyjnie, czy możną używać pola reprezentującego klucz główny tabeli w tych metodach.


Najpierw trochę literatury:
http://community.jboss.org/wiki/EqualsandHashCode

https://forum.hibernate.org/viewtopic.php?t=928172

http://onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html?page=2

Wnioski z tego, z czym się do tej pory zapoznałem, są takie, że Hibernate mówi: nie używajcie ID, ale jak już musicie, to przynajmniej upewnijcie się, że obiekty (które będą porównywane) są w tej samej sesji! Dlatego proponuję otwartą dyskusję na ten temat. Obecnie przyjąłem sobie następujący schemat pisania equals() i hashCode(). W equals() biorę pod uwagę tylko id jeśli oba obiekty mają ustawione id (w moim przypadku różne od 0). W przeciwnym wypadku porównuję odpowiednie pola. W hashCode() nie wykorzystuje id, ponieważ może dojść do sytuacji, w której 2 obiekty takie same, będą miały różne hashe.
    @Override
    public boolean equals(Object object) {
        
        if (this == object) return true;
        
        if ( !(object instanceof Entity) ) return false;
        
        Entity entity = (Entity) object;
        
        if (id != 0 && entity.getId()!=0){            
            return id == entity.getId();
        }
        return new EqualsBuilder().append(field, entity.getField())
            ...//i inne pola
            .isEquals();
   }

Brak komentarzy:

Prześlij komentarz