How do you get equals() working with Hibernate entities when lazy=true?
For some reason when lazy=true on all my entities, the equals() method does not work correctly when one side is a lazily-loaded entity and the other side is a normal entity. Here's an example:
if(activeTask.getTask().equals(task)) {...}
In this case, the activeTask's task will be a proxy while the right side will be a regular one. The equals() will fail. To fix this problem, I often do things like this:
if(activeTask.getTask().getId() == task.getId()) {...}
This works, but it's not ideal. I'd rather use my equals() method.
Does anyone have a nice solution to this problem? It really adds to the application's level of noise to have to think about stuff like this.
If I say lazy=false, I don't have to deal with proxy's, and so equals() will work. But this has a very negative impact on performance.
It is just not cool to have to say, "equals() works in all cases, except whe开发者_运维知识库n you use proxies... then equals() is not reliable."
I realize this is an old question, but it's still unanswered and people might stumble upon it.
I had the same problem a few days ago. In the project we use an abstract base class BasicEntityType
, which has just an ID and equals is implemented in said base class:
@Override
public final boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
Class<?> objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(obj);
if (this.getClass() != objClass) {
return false;
}
if (id == null) {
return false;
}
return id.equals(((BasicEntityType) obj).getId());
}
There are two critical parts in this code:
- First: Do not check directly for class equality, it might not work with the given object.
- Second: All properties of the given object have to be accessed by using methods. Or you could unwrap the actual object.
精彩评论