hashCode() и equals() класса составного идентификатора

Уже несколько дней я пытаюсь найти правильный способ реализации методов equals() и hashCode() класса составного идентификатора.

Проблема, с которой я сталкиваюсь, когда пытаюсь обновить основной объект (Гара):

  1. Переполнение стека
  2. DuplicateKeyException: другой объект с тем же значением идентификатора уже был связан с сеансом
  3. org.hibernate.ObjectNotFoundException: не существует строки с данным идентификатором

Мой класс Composite-id

@Embeddable 
public class GaraAgenziaId implements Serializable {

    private static final long serialVersionUID = 4934033367128755763L;

    static Logger logger = LoggerFactory.getLogger(GaraAgenziaId.class);

    private Gara gara;

    private Agenzia agenzia;

    @ManyToOne
    public Gara getGara() {
        return gara;
    }

    public void setGara(Gara gara) {
        this.gara = gara;
    }

    @ManyToOne
    public Agenzia getAgenzia() {
        return agenzia;
    }

    public void setAgenzia(Agenzia agenzia) {
        this.agenzia = agenzia;
    }


    @Override
    public String toString() {
        return "GaraAgenziaId [Gara=" + gara + ", agenzia=" + agenzia
                + "]";
    }


}

person SaganTheBest    schedule 15.07.2014    source источник


Ответы (1)


они, кажется, работают очень хорошо:

 public boolean equals(Object o) {
        if (this== o) return true;
        if (o ==null|| getClass() != o.getClass()) return false;

        GaraAgenziaId that = (GaraAgenziaId) o;

        if (gara !=null?!gara.equals(that.gara) : that.gara !=null) return false;
        if (agenzia !=null?!agenzia.equals(that.agenzia) : that.agenzia !=null)
            return false;

        return true;
    }

    public int hashCode() {
        int result;
        result = (agenzia !=null? agenzia.hashCode() : 0);
        result =31* result + (gara !=null? gara.hashCode() : 0);
        return result;
    }   
person SaganTheBest    schedule 16.07.2014
comment
Не рискует ли 31*a + b переполниться? - person Mindwin; 08.11.2016
comment
@Mindwin извините, но я недостаточно эксперт, поэтому не могу вам ответить. Это был фрагмент кода, найденный где-то, и он работал для моей цели. - person SaganTheBest; 06.03.2017
comment
Он будет переполнен, но без ошибок, поэтому он по-прежнему будет эффективен в качестве хэш-кода. - person Ian Robertson; 29.01.2018
comment
@IanRobertson Во-первых, большое спасибо за ваш комментарий. Но я смог увидеть ваш ответ только по счастливой случайности (я просматривал свой помеченный список). Не забывайте @цитировать!! XD - person Mindwin; 27.03.2018