4

My question concerns EntityManager.getReference. Given that I am in one JPA session, can I be sure that for two calls to EntityManager.getReference for the same entity and the same primary key I always get the same instance of java object ? For two distinct sessions I'd suspect to get two different instances of java objects - is it really the case ?

I am interested to know the general rule, not how any specific implementation works. Is it defined by the spec or not ? (I was unable to find it out myself).

Person p1 = EntityManager.getReference(Person.class, 1L);
Person p2 = EntityManager.getReference(Person.class, 1L);

if (p1 == p2) {
  System.out.println("SAME");
} else {
  System.out.println("DIFF");
}
  • Maybe this will help: http://stackoverflow.com/questions/1607532/when-to-use-entitymanager-find-vs-entitymanager-getreference – JMelnik Jun 13 '12 at 08:12

1 Answers1

3

Yes, it's a basic guarantee of JPA - within the scope of persistence context (i.e. session, EntityManager) object identity of managed entities matches their database identity:

7.1 Persistence Contexts

A persistence context is a set of managed entity instances in which for any persistent entity identity there is a unique entity instance.

and getReference() returns a managed instance:

3.2.8 Managed Instances

...

The contains() method can be used to determine whether an entity instance is managed in the current persistence context.

The contains method returns true:

  • If the entity has been retrieved from the database or has been returned by getReference, and has not been removed or detached.
  • If the entity instance is new, and the persist method has been called on the entity or the persist operation has been cascaded to it.

Moreover, this guarantee means that inside the scope of persistence context you'll get the same instance of entity for the same id no matter how you obtained it (via find(), getReference(), merge(), query or relationship traversal).

For example, if you obtained a proxy from getReference() all further work with that entity will happen through that proxy:

Person p1 = EntityManager.getReference(Person.class, 1L); 
Person p2 = EntityManager.find(Person.class, 1L); 
assertSame(p1, p2);

See also:

Community
  • 1
  • 1
axtavt
  • 228,184
  • 37
  • 489
  • 472