Bug 153738 - [hashcode/equals] Support using superclass fields and methods (getters)
Summary: [hashcode/equals] Support using superclass fields and methods (getters)
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.2   Edit
Hardware: All All
: P3 normal with 4 votes (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
: 164596 225796 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-08-14 05:19 EDT by Kaj Hejer CLA
Modified: 2022-08-25 18:10 EDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kaj Hejer CLA 2006-08-14 05:19:30 EDT
When using hibernate I want to have equals and hashCode methods in my POJOs for my database tables. We use the generation gap pattern for these classes so we have BasePerson (which is generated by hibernate tools and just contains the fields from the database and we have Person which extends BasePerson and contains our hand written code for persons.

We want our equals and hashCode methods to be in the Person class (not in the BasePerson) so we don't need to regenerate this methods each time we regenerate the BasePerson class.

The equals and hashCode methods generated with eclipce 3.2 don't have an option to use methods instead of variables (getName() vs name) so we can't move the equals and hashCode methods we generate in BasePerson to Person.

A solution to this issue could be to add an option in the generate hashcode and equals methods to specify if you want to use variables or methods.

Another solution to this issue could be to add an option for looking in the superclass for fields to include in the hashcode and equals method.
Comment 1 Andre Weinand CLA 2006-08-18 17:33:41 EDT
[not Mac specific; setting HW/OS to All)
Comment 2 Martin Aeschlimann CLA 2006-08-22 10:44:21 EDT
One could argue that 'super.hashCode()' is sufficient for that. But offering the (visible) fields from the super class makes sense.

The wish to also offer methods has also already been brought up. I'm not yet convinced, but maybe we can just offer a filter for methods (with no arguments) and super fields.
super.hashCode() could also be shown as a node to check or uncheck.
Comment 3 Caleb Phillips CLA 2006-09-27 14:24:31 EDT
There is another situation when it would be useful to call the getters instead of using direct field access.  When using Hibernate, the field in the generated proxy may be null, but calling the getter will still return the correct (non-null) value

(In reply to comment #2)
> One could argue that 'super.hashCode()' is sufficient for that. But offering
> the (visible) fields from the super class makes sense.
> 
> The wish to also offer methods has also already been brought up. I'm not yet
> convinced, but maybe we can just offer a filter for methods (with no arguments)
> and super fields.
> super.hashCode() could also be shown as a node to check or uncheck.
> 

Comment 4 Martin Aeschlimann CLA 2006-11-15 17:25:21 EST
*** Bug 164596 has been marked as a duplicate of this bug. ***
Comment 5 Martin Aeschlimann CLA 2006-11-15 17:26:21 EST
Extending this request to methods (getters). 
Comment 6 Alex Blewitt CLA 2006-11-16 05:22:22 EST
I'm not sure it makes sense for a subclass to use the superclass' fields for computing equality, when the equality check could be implemented at a higher level anyway. In the case of having a BasePerson automatically generated, it seems that a better way of solving it would be to put the equals and hashcode in there when it's generated too.

I like the idea of the properties though. Perhaps the dialog that prompts the message could be given an option to calculate the equality based on whatever JavaBeans-type properties (getter/is methods; but all visible ones, whether public or protected etc.) are available to that class.

In fact, this would be a useful way of being able to compare different object types (which can't easily be done with the .equals() method at present) such as comparing a URI and URL. However, you still run into the problem that the .equals method for the URI has to be the same as the .equals method for the URL in order to make sense, so it's not completely safe.

One place where I would have been able to use the properties-equality was when having a collection of POJOs and EJBs on a prior project. The EJB and POJO weren't directly comparable (one implemented Remote, the other didn't) but had we had equality based on get() methods, it would have worked. (In the end, we had a supporting method called convertToPojo() that returned 'this' for the POJO and did a conversion for the EJB, so we used that when we were doing comparisons).

What would happen in the case of exceptions being thrown (either declared or runtime) during the equality check? Would you propagate the exception via an untyped exception e.g. IllegalStateException?

try {
 ...calculate equality with getMethods()
} catch (RuntimeException e) {
  throw e;
} catch (Exception e) {
  throw new IllegalStateException("Exception failed whilst calculating equality", e );
}

Alex.
Comment 7 Aaron Digulla CLA 2006-11-16 08:19:11 EST
> I'm not sure it makes sense for a subclass to use the superclass' fields
> for computing equality[...]

There will always be someone who eventually needs it. As long as it's not dangerous to do it, you should allow it.

> What would happen in the case of exceptions being thrown[...]?

Getters must not throw checked exceptions. It's in the contract, so we're safe here.

And since equals() cannot handle the runtime exceptions (what should it do with them?), it must not catch them.
Comment 8 Alex Blewitt CLA 2006-11-16 10:19:25 EST
You'd have to take into account what would happen, though. Strictly, JavaBeans properties have to be public too -- but that doesn't mean you shouldn't consider get() methods that are protected (or friendly, or even private) for this method.

Note that section 7.3 of the JavaBeans specification explicitly allows for JavaBean Properties accessor methods to throw exceptions:

http://sdlc-esd.sun.com/ESD4/JSCDL/javabeans/1.01/beans.101.pdf?AuthParam=1163689822_24a0fee18bb77f3f6aad51ce908da115&TUrl=an1npDpbKod7kSYrROhENTonIeQ2W0D1Lc4nXz+pGFFranixdCdgxDTPbW4=&TicketId=dll9PwBJNOk4/w==&GroupName=SDLC&BHost=sdlc5i.sun.com&FilePath=/ESD4/JSCDL/javabeans/1.01/beans.101.pdf&File=beans.101.pdf

"7.3 Exceptions on accessor methods 
Both simple and indexed property accessor methods may throw checked exceptions. This
allows property setter/getter methods to report exceptional conditions. 
Thus for example you might have: 
void setWombat(Wombat value) throws BadWombatException; 
Marsupial getKangaroo(int index) throws AwfulCommunicationException; "

Otherwise, you'd end up in a potential scenario where generation of a method that called a getter that threw an exception would result in a compilation error.

You could, of course, only show accessible getter methods that don't throw exceptions, thus sidestepping the issue.

PS The code that catches and re-throws the runtime exception is to stop the RuntimeException being swallowed by wrapping it around another RuntimeException. It's fairly standard practice to have a 'catch everything except' type block, and also keeps the stacktrace and line numbers visible to any callers who are handling it. It's unnecessary if you're not also catching generic Exceptions.

PPS Strictly speaking, a JavaBeans property need not start with get(), either. If a BeanInfo class is provided, you can set up mappings to link non-standard method names with property accessors. java.beans.Introspector.getBeanInfo(clazz) will return a BeanInfo object that contains all the properties for that class. If none are provided, it will instantiate a BeanInfo that uses the standard method names of get/set and the special-case is. I would suggest that if doing this approach, using the union of any visible 'get' methods and the readable properties of the resultant BeanInfo are used to present the list of options to the user.
Comment 9 Kaj Hejer CLA 2006-11-16 15:34:00 EST
Thanks for looking into this issue! 

The most importent part of this issue is the use of getters, ref. comment #3. Today we have to write all our hash/equals by hand because of the issues described in comment #3. 

The superclass part of this issue is not that important :)
Comment 10 Martin Aeschlimann CLA 2008-04-07 04:49:48 EDT
*** Bug 225796 has been marked as a duplicate of this bug. ***
Comment 11 Miguel CLA 2011-02-21 12:02:52 EST
In a discussion regarding the Hibernate ORM - and the possible need for this to be implemented - I decided to search for an open ticket on this issue.

Can this be implemented?

I'm sure this is quite easy. If you want I can help with the template.
Comment 12 Markus Keller CLA 2011-02-23 06:08:18 EST
We have no plans to work on this, but we would accept a high-quality patch.

If you want to work on this, please indicate it here, so that we can discuss your proposed UI and functionality before you start with the implementation.
Comment 13 Eclipse Genie CLA 2020-07-27 19:45:48 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 14 Eclipse Genie CLA 2022-08-25 14:41:51 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.