Сравнение отложенных объектов Spring Data MongoDB с использованием equals/hashCode

у меня есть два объекта

  • Один с ленивой загрузкой

      product:5757b95d1d8eecdd01e59b29$LazyLoadingProxy
    
  • Другой нетерпеливый загружен

      com.entity.Product@5e6c4568
    

Я знаю, что оба объекта одинаковы, так как они имеют одинаковый уникальный идентификатор (id=5757b95d1d8eecdd01e59b29).

У меня есть в моем классе Product следующие методы:

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (prime * result) + ((id == null) ? 0 : id.hashCode());
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final Item other = (Item) obj;
    if (id == null) {
      if (other.id != null) {
        return false;
      }
    } else if (!id.equals(other.id)) {
      return false;
    }
    return true;
  }

Но теперь, когда я выполняю следующую операцию, я не получаю совпадений. Любые подсказки?

temp.contains(product) == false

temp содержит лениво загруженные элементы, а product содержит обычные элементы.


person Saurabh Kumar    schedule 08.06.2016    source источник
comment
Подсказка: Ваш метод equals преобразует obj в Item. Это либо ошибка, либо неочевидно, что Product extends Item.   -  person mp911de    schedule 09.06.2016


Ответы (1)


Короче говоря

Именно так вы реализовали equals.

Объяснение

Spring Data MongoDB создает прокси-серверы с отложенной загрузкой, используя библиотеки генерации кода. Класс лениво загруженной ссылки во время выполнения будет чем-то вроде com.example.Product$$EnhancerByCGLIB$$5f3cdccd. Ваша реализация выполняет проверку точного типа класса

if (getClass() != obj.getClass()) {
  return false;
}

это заставляет equals возвращать false. Более дружественный вариант проверки:

if (!(o instanceof Product)) {
    return false;
}

Также имейте в виду, что в зависимости от того, какой экземпляр находится в коллекции и какой передается в contains(), методы equals и hashCode вызываются либо в прокси-экземпляре, либо в классе сущности. Это не относится к проверке id, так как поле id всегда заполнено, но оно будет иметь значение, если вы попытаетесь сравнить другие свойства. Причина в том, что поля прокси не инициализированы (и не будут инициализированы), поскольку разрешенный объект хранится отдельно. Это означает, что для сравнения свойств, отличных от id, требуются вызовы их геттеров.

person mp911de    schedule 09.06.2016