To be honest,

I started on this project a couple of years ago and the abstract entity class 
has always contained the following and I have not really looked into what the 
reflection equals and hashcode do ...

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (this == obj) {
            return true;
        }

        if (!(obj instanceof AbstractEntity)) {
            return false;
        }

        AbstractEntity entity = (AbstractEntity) obj;
        if (getId() != null || entity.getId() != null) {
            return new EqualsBuilder().append(getId(), 
entity.getId()).isEquals();
        } else {
            return EqualsBuilder.reflectionEquals(this, obj);
        }
    }

    @Override
    public int hashCode() {
        if (getId() != null) {
            return new HashCodeBuilder().append(getId()).toHashCode();
        } else {
            return HashCodeBuilder.reflectionHashCode(this);
        }
    }

The getId() method is a pure getter, which relates to a PK in a DB table. There 
are some instances where the objects that implement the AbstractEntity override 
the equals method to include the use of a unique key, however, these objects 
generally don't override hashCode so I would think this would be a potential 
problem. I'm looking to corrected that where  find it.

So I'm removing the hashCode() out of the abstractEntity, hopefully if would 
affect performance too much, will implement the hashCode in objects that 
actually require it.

As for performance, as you say, that reflectionHashCode did make performance 
really slow, took almost 2 mins to copy an object, without it, about a second.

Thanks for your help

Dale Ellis

-----Original Message-----
From: Jörg Schaible [mailto:[email protected]] 
Sent: 15 November 2013 09:10
To: [email protected]
Subject: [xstream-user] RE: RE: RE: RE: Re: Converting an object back from XML

Hi Dale,

Dale Ellis wrote:

> I was having a look in the JConsole at the stack of the hanging 
> thread, I think the issue is to do with my abstractEntity class (which 
> all the JPA entity objects extend) overrides the hascode with this...
> 
>     public int hashCode()    {
>         if(getId() != null)
>         {
>             return new HashCodeBuilder().append(getId()).toHashCode();
>         }
>         else
>         {
>             return HashCodeBuilder.reflectionHashCode(this);
>         }
> 
> When I remove this, the fromXML() works

The reflectionHashCode is a *very* dangerous tool (I don't give a bad mouth 
here, I am committer to Apache Commons Lang myself). In your case you might 
even break the hashCode contract. The hashCode is meant to be a *constant* 
unique identifier, i.e. if you use your object as key in a HashMap, the hash 
value should never change afterwards. Is getId() a pure getter or will it also 
access other complex objects in the graph to get one?

From the XML structure I can see that some of your objects deep down in the 
object graph contain back references to parents or siblings. A reflection- 
based hash code builder will normally silently introduce an endless recursion 
here - it just works, because the Apache implementation keeps track of the 
accesses objects. However, this calculation is in any case expensive.

BTW: Are you also sure you fullfill another hash code contract, i.e. equal 
equal objects (calling equals()) means also equal hash codes (the reverse is 
not guaranteed though)?

Apart from this, I still wonder, why TreeMap.putAll adds all elements 
individually instead of using the optimized method that does not sort the 
elements again and therefore omit all calls to compareTo ... :-/

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to