Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

257
Vistas
Java @Override equals(): Cuando this.getClass() != o.getClass() falla pero no debería

Tengo este @Override for equals() en mi clase MyClass :

 @Entity( name = "MyClass" ) @Table( name = "my_class" ) public class MyClass extends MySuperClass { ... @Override public boolean equals( Object o ) { if ( this == o ) { return true; } if ( o == null || this.getClass() != o.getClass() ) { return false; } if ( !super.equals( o ) ) { return false; } MyClass that = ( MyClass ) o; return this.var1.equals( that.var1 ) && this.var2.equals( that.var2 ); } ... }

Bastante estándar. De hecho, sigue las mejores prácticas de Java.
Más tarde en la vida tengo esto en otra clase de subpaquete (mi clase de controlador):

 ... package com.abapi.controllers; ... import com.abjpa.models.MyClass; ... MyClass myObject1 = new MyClass( var1, var2 ); MyClass myObject2 = this.myClassRepository.getById( 1 ); // SpringBoot/Jpa/Hibernate if ( myObject2.equals( myObject1 ) ) { ...do something... } ... this.myClassRepository.save( myObject1 ); ...

Mi problema es que .equals() siempre falla aquí:

 if ( o == null || this.getClass() != o.getClass() )

porque java dice que this.getClass() y o.getClass() NO son iguales. Cuando depuro el código (en Intellij IDEA 2022.1 UE) veo esto:

this.getClass() = MiClase@13706

pero

o.getClass = com.abjpa.models.MyClass@8f7462

¡Pero son de la misma clase! Casi todos los libros, tutoriales, blogs, Intellij IDEA, etc. de Java demuestran el .equals() de esta manera. Probé esto en Ubuntu 20.04.4 LTS java-14-openjdk-amd64 y java-17-openjdk-amd64 con los mismos resultados.

¿Qué estoy haciendo mal?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

myObject2 es una instancia de una clase proxy, generada en tiempo de ejecución por Hibernate usando Byte Buddy . El proxy generado intercepta todas las invocaciones de métodos, por eso getClass() devuelve resultados diferentes.

Como alternativa a getClass() , el uso de instanceof podría ser otro enfoque:

 if ( !(this instanceof MyClass && o instanceof MyClass) ) { return false; }

Sin embargo, tenga en cuenta que instanceof tiene sus inconvenientes . Viola el principio de simetría.

En primer lugar, no debe comparar estos objetos, ya que un objeto nuevo debe ser diferente de uno administrado por Hibernate que tiene un estado persistente.

over 4 years ago · Santiago Trujillo Denunciar

0

Utilizo estas implementaciones estándar de hashcode y equals para entidades JPA (como se describe aquí ):

 @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof MyClass)) { return false; } MyClass other = (MyClass) o; return id != null && id.equals(other.getId()); } @Override public int hashCode() { return getClass().hashCode(); }
over 4 years ago · Santiago Trujillo Denunciar

0

No está utilizando una mejor práctica. Cambie sus iguales para que sean algo como lo siguiente (verificación nula primero, luego la misma verificación, luego verificación de clase):

 public boolean equals(Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } if (obj.getClass() != getClass()) { return false; } ... do the actual comparison here }

Nota: el código anterior es una paráfrasis de Apache EqualsBuilder

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda