Reputation: 1695
I have implemented hashCode()
and equals()
for an object using the default from 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;
}
At the logging check-points, I get:
units.UnitSystem - class com.utilities.domain.units.UnitSystem
units.UnitSystem - org.springframework.boot.devtools.restart.classloader.RestartClassLoader@42d353e2
units.UnitSystem - class com.utilities.domain.units.UnitSystem_$$_jvst6b1_19ed
units.UnitSystem - org.springframework.boot.devtools.restart.classloader.RestartClassLoader@42d353e2
The equality fails at that point and equals
returns false.
What is the extra _$$_jvst6b1_19ed
? Where does it come from?
From what I understand, the classes should be equal if they are from the same class loader, which these are. I have not had a problem with this implementation anywhere else I have used it. Why is getClass()
returning different things?
Upvotes: 1
Views: 233
Reputation: 159135
Unless you actually subclass UnitSystem
yourself, exact class matching isn't necessary, so replace
if (getClass() != obj.getClass()) {
return false;
}
with
if (! (obj instanceof UnitSystem)) {
return false;
}
You can't make UnitSystem
class final
since you want Hibernate to be able to create a subclass proxy, so you don't have absolute guarantee that UnitSystem
won't be subclassed by non-Hibernate code, but is such an absolute guarantee really needed?
Upvotes: 3
Reputation: 2558
As @Andreas said in a comment it usually happens when the object has been fetched by a lazy loading. To get the initial object you should to unproxy it first. Here is an example of the unwrapper for a 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;
}
Upvotes: 0