Java равняется реализации для двух объектов одного класса, возвращает false при проверке getClass () - PullRequest
0 голосов
/ 25 октября 2018

Я реализовал hashCode() и equals() для объекта, использующего значение по умолчанию из NetBeans:

@Override
public int hashCode() {
    int hash = 5;
    hash = 37 * hash + this.unitSystemID;
    return hash;
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    LOGGER.debug(getClass().toString());
    LOGGER.debug(this.getClass().getClassLoader().toString());
    LOGGER.debug(obj.getClass().toString());
    LOGGER.debug(obj.getClass().getClassLoader().toString());
    if (getClass() != obj.getClass()) {
        return false;
    }
    final UnitSystem other = (UnitSystem) obj;
    if (this.unitSystemID != other.unitSystemID) {
        return false;
    }
    return true;
}

На контрольных точках регистрации я получаю:

units.UnitSystem - класс com.utilities.domain.units.UnitSystem

units.UnitSystem - org.springframework.boot.devtools.restart.classloader.RestartClassLoader@42d353e2

unit.UnitSystem - классcom.utilities.domain.units.UnitSystem _ $$ _ jvst6b1_19ed

units.UnitSystem - org.springframework.boot.devtools.restart.classloader.RestartClassLoader@42d353e2

1017 при *1016* 1017 приэта точка и equals возвращает ложь.

Что такое дополнительные _$$_jvst6b1_19ed?Откуда это взялось?

Из того, что я понимаю, классы должны быть равными, если они принадлежат одному и тому же загрузчику классов.У меня не было проблем с этой реализацией где-либо еще, я использовал ее.Почему getClass() возвращает разные вещи?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Если вы на самом деле не подкласс UnitSystem, точное соответствие классов не требуется, поэтому замените

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

на

if (! (obj instanceof UnitSystem)) {
    return false;
}

Вы не можете сделать UnitSystem классfinal, поскольку вы хотите, чтобы Hibernate мог создавать прокси подкласса, поэтому у вас нет абсолютной гарантии того, что UnitSystem не будет разделен на подклассы не-Hibernate-кодом, но действительно ли такая абсолютная гарантия действительно необходима?

0 голосов
/ 25 октября 2018

Как сказал @Andreas в комментарии, это обычно происходит, когда объект выбирается с помощью отложенной загрузки.Чтобы получить начальный объект, вы должны сначала снять с него прокси.Вот пример распаковщика для Hibernate

 @SuppressWarnings("unchecked")
  public static <T> T initializeAndUnproxy(T entity) {
    if (entity == null) {
      throw new InternalServerException("Entity passed for initialization is null");
    }

    T unproxy = entity;
    Hibernate.initialize(entity);
    if (isProxy(entity)) {
      unproxy = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
    }
    return unproxy;
  }

  public static <T> boolean isProxy(T entity) {
    return entity instanceof HibernateProxy;
  }
...