Hibernate version:Hibernate Annotations 3.3.1.GA, Hibernate 3.2.6, Hibernate EntityManager 3.3.2.GA
Hi, all. From reading the hibernate manual, hibernate "guarantees" object identity for your persistent objects within a single session. That's what I'd expect (and want) after years of toplink experience. However, it's not what I'm seeing. This appears to be a bug to me, but since it's so fundamental to hibernate (I would think), I wanted to post it here to see if anyone can see something obvious I'm doing wrong before I enter it as a bug.
Here's the mapped class:
Code:
package com.foo.client.dataobject;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
/**
* Data object that contains information about one of our clients.
*/
@Entity
@Table(name = "client")
public class Client {
@Id
@Column(name = "id")
@Type(type = "com.foo.dbspecific.UUIDType")
@GeneratedValue(generator = "inf-uuid")
@GenericGenerator(name = "inf-uuid", strategy = "com.foo.dbspecific.UUIDGenerator")
protected UUID mId;
@Column(name = "name")
private String mName;
// Some other columns....
/**
* Default constructor for JPA.
*/
Client() {
}
// Other methods...
}
(Note that hashCode() and equals() are not overwritten.) The test code:
Code:
...
public class ClientDaoTest extends AbstractTransactionalTestNGSpringContextTests {
@PersistenceContext
private EntityManager em;
@Test(groups = { "functional" })
public void identityTest() {
Client c = (Client)em.createQuery("from Client c").getResultList().get(0);
System.out.println("C ID IS " + c.getId() + ", hashCode " + c.hashCode());
Client c2 = em.find(Client.class, c.getId());
System.out.println("C2 ID IS " + c2.getId() + ", hashCode " + c2.hashCode() + ", ==? " + (c == c2));
Client c3 =
(Client)em.createQuery("from Client c where c.mId = :id").setParameter("id", c.getId())
.getSingleResult();
System.out.println("C3 ID IS " + c3.getId() + ", hashCode " + c3.hashCode() + ", ==? " + (c == c3));
}
}
You (or at least I) would expect that the hashcodes for c, c2, and c3 would all be the same, and they would all "==" each other. However, this is the case only for c2 and c. Relevant output:
Code:
12:57:38.967 [1] DEBUG o.h.SQL: select client0_.id as id0_, client0_.database_user as database2_0_, client0_.insert_tm as insert3_0_, client0_.last_update_tm as last4_0_, client0_.name as name0_, client0_.status as status0_ from client client0_
C ID IS 0d2965a3-ce74-4b6f-926b-146420d20d12, hashCode 23578365
C2 ID IS 0d2965a3-ce74-4b6f-926b-146420d20d12, hashCode 23578365, ==? true
12:57:39.279 [1] DEBUG o.h.SQL: select client0_.id as id0_, client0_.database_user as database2_0_, client0_.insert_tm as insert3_0_, client0_.last_update_tm as last4_0_, client0_.name as name0_, client0_.status as status0_ from client client0_ where client0_.id=?
C3 ID IS 0d2965a3-ce74-4b6f-926b-146420d20d12, hashCode 28280066, ==? false
As this output indicates, no select is done to retrieve c2, and it is == to c. It also indicates a select is necessary to load c3 (not too surprising), but (surprisingly) c3 != c.
If someone thinks that the UUIDGenerator or UUIDType source code, the full log, persistence.xml, etc., are worth viewing, I'm happy to add that info as well -- just don't want to waste my time doing so if it's not relevant...
Thanks in advance,
Greg