Hi Adam,
I don't think that's a good idea long-term. Equals/hashcode usually targets the
smallest set of business properties which can identify an object. Also, while
reflection got much faster these days, heavy performance issues might still
arise as especially hashcode() is called a lot.
You might further develop your idea with using EqualsBuilder/HashcodeBuilder
from Jakarta Commons Lang, adding an abstract method defining the essencial
properties to include in the generated equals/hashcode and add caching to
hashcode values, but still, understanding and writing a proper equals/hashcode
manually looks a much easier/safer path for me.
my 2c,
Kristof
Adam Hardy wrote:
> I put a superclass on all my entities for a couple of general properties
> that they all share, and now I'm considering putting my equals() and
> hashCode() methods into the superclass as well, with reflection to loop
> over the array of child methods, calling whatever POJO getters are present.
>
> The advantage in terms of not needing to maintain the equals, hashCode
> and toString methods on every entity is quite attractive, but I'm
> worried about
>
> (a) performance
> (b) any nasty surprises it might cause in JPA entity management
>
> With (a), performance will be hit if an entity has large collections of
> one-to-many or many-to-many related entities. I might be able to get
> around quite easily though.
>
> With (b) it seems more problematic, for instance calling the equals()
> might get stuck in an endless loop if I have any circular relationships
> in my model, which would otherwise be benign if only loaded by lazy
> loading.
>
> Sorry that this isn't directly an OpenJPA question.
>
> This is the kind of thing I'm thinking of:
>
> public boolean equals(Object object) {
> if (this == object) return true;
> if (object == null) return false;
> if (!(object instanceof TradeHistory)) return false;
> TradeHistory other = (TradeHistory) object;
> boolean equal = false;
> Method[] methods = this.getClass().getMethods();
> for (int i = 0; i < methods.length; i++) {
> Method method = methods[i];
> if (method.getName().equalsIgnoreCase("GETCLASS")) continue;
> if ((method.getName().startsWith("get"))
> && (method.getParameterTypes().length == 0)) {
> try {
> Method otherMethod =
> other.getClass().getMethod(method.getName(),
> new Class[] {});
> equal &=
> isEqual(method.invoke(this, new Object[] {}),
> otherMethod
> .invoke(other, new Object[] {}));
> }
> catch (Exception e) {
> }
> }
> }
> return equal;
> }