What is the difference between EntityManager.find() and EntityManger.getReference()?

JPA has the concept of an EntityManager, as you know. During your work in the entity manager some objects are loaded from the database, can be modified and afterwards flushed to the database.

find() has to return an initialized instance of your object. If it is not already loaded in the EntityManager, it is retrieved from the database.

getReference() is allowed to return a proxy instead of an initialized instance, if the entity has not been loaded in the EntityManager before. In this proxy, only the primary key attribute is initialized. Proxies can be created without hitting the database, because the only initialized attribute is already given to the getReference() function.

The latter is useful when you have an entity A referencing an entity B, and you want to set the b-attribute of A to B, without having to load B from the database.

Only if you reference other attributes of B, the proxy will be initialized.


The book Beginning Java EE 6 Platform with GlassFish 3, mention the differences in page 135: "Finding By ID"

find() if the entity is found, it is returned; if it is not found, a null value is returned.

MyEntity obj = em.find(MyEntity.class, id);
if(obj != null){
   // Process the object 
}

getReference() is intended for situations where a managed entity instance is needed, but no data, other than potentially the entity's primary key, being accessed.

try {
    MyEntity obj = em.getReference(MyEntity.class, id);
    // Process the object
} catch (EntityNotFoundException e) {
    // Entity Not Found
}

getReference() does not retrieve the full object but only a proxy and therefore can be more efficient if you do not access the members of the object.

For instance when creating a new object to insert into your database, it might have to refer to another object which already has been stored in the database.

For JPA to store the new object correctly only the primary key of the referred object is needed. By using getReference() you get a proxy which contains the primary key and you save the cost of loading the complete object.