Bug 164596 - [hashcode/equals] Generated equals() is broken when using Hibernate
Summary: [hashcode/equals] Generated equals() is broken when using Hibernate
Status: RESOLVED DUPLICATE of bug 153738
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.2.1   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-11-15 03:41 EST by Aaron Digulla CLA
Modified: 2006-11-15 17:25 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Aaron Digulla CLA 2006-11-15 03:41:09 EST
The generated code for equals() contains:

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

Unfortunately, when you use Hibernate, this can be false even if you compare an object to itself!

The reason for this is that Hibernate creates derived class instances on the fly with CGLIB. One place where this happens is if you have an object with children which contain back references.

If you navigate parent->child->parent, the second parent object can have a different class as the first because Hibernate has to inject code to implement lazy loading (Hibernate creates a new class which contains proxy code which loads the objects from the database when you call the getter for the first time).

Unfortunately, there is no good solution. Usually with the Java contract, two objects of a different class cannot be equal.

If you have "class B extends A {}" (ie. a new class which doesn't change the behavior of A since it doesn't add new methods or fields), then one could argue that all objects of B are in fact of the same class as A.

As a next step, are two objects different if their business key is the same?

For example if I create a derived class which adds code to display the object in a UI but doesn't change the behavior. Since I can exclude fields from the generated equals() code, I would argue that they are the same.

Therefore, can you please change the generated code to:

        if (!(obj instanceof A) )
            return false;

This would make sure the cast works. If you don't want to make this the default, please add an option to the field selection dialog.

And last but not least, please use the getters to access the field values (for the same reason) or add an option for this. With Hibernate, all fields are always "null" because the getters contain some magic.

Also, given the Java idea of getters, you should never assume that it's save to use the fields directly when a getter exists.
Comment 1 Martin Aeschlimann CLA 2006-11-15 17:25:21 EST
The 'instanceof' option got added for 3.3 (see bug 129547)
The suggestion of supporting getters is in bug 153738.

I hope it's ok if I set this as a dup of bug 153738

*** This bug has been marked as a duplicate of 153738 ***