Atul Acharya
Atul Acharya

Reputation: 507

Strange behaviour in JPA2 entities

While observing some log entries, I observed a behaviour, I do not understand. I have recreated the scenario.

The entity:

@Entity
public class SimpleEntity implements Serializable {

    private static final long serialVersionUID = 2777681889998131084L;

    @Id
    @GeneratedValue
    private Long id;
    @Version
    private Long version;
    @Column(length = 20, nullable = false, unique = true, updatable = false)
    @NotNull
    private String username;
    @Column(length = 60)
    private String email;

    // Constructors

    // getters/setters

    // @Override
    // toString : generated by eclipse, modified to include super.toString
    // hashCode, equals : generated by eclipse, based on 'username'

}

The Testcase

@Test
public void testUpdate() {
    SimpleEntity simple;
    SimpleEntity simple2;

    try {
        simple = bean.create(new SimpleEntity("user",
                "[email protected]"));  // em.persist
        simple.setEmail("[email protected]");
        simple2 = bean.update(simple);          // em.merge
        System.out.println(simple);
        System.out.println(simple2);
    } catch (EJBException e) {
        System.out.println(e.getMessage());
    }
}

It prints following lines corresponding to above System.out.println lines

...SimpleEntity@36ebea SimpleEntity [id=1, version=1, username=user, [email protected]]
...SimpleEntity@36ebea SimpleEntity [id=1, version=2, username=user, [email protected]]

What I find strange is the address is same for both entities (SimpleEntity@36ebea), but if I look at the data, it is not same. 'version' is different. (1 & 2)

How can same instance (as address is same), show different data? Is there some proxy in play? how?

Upvotes: 0

Views: 113

Answers (1)

zagyi
zagyi

Reputation: 17518

simple and simple2 are actually two different instances. You said that "toString : generated by eclipse, modified to include super.toString". The inherited toString() from Object looks like:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

So @36ebea is not the object's address, but its hashcode which (being based only on username) remains the same for different instances where only the version differs.

You might want to use System.identityHashCode() to get a hashcode derived from the object's address (it basically returs what you would get from calling hashCode() if you didn't override the one inherited from Object).

Upvotes: 1

Related Questions