the getReference( ) method is discussed well in the pro EJB3.0 book.
There exists a special version of find() that may be used in one particular situation. That situation is when a relationship is being created between two entities in a one-to-one or many-to-one relationship where the target entity already exists and its primary key is well-known. Since we are only creating a relationship, it may not be necessary to fully load the target entity in order to create the foreign key reference to it. Only its primary key is required. The getReference() operation may be used for this purpose. Consider the following example:
Department dept = em.getReference(Department.class, 30);
Employee emp = new Employee();
emp.setId(53);
emp.setName("Peter");
emp.setDepartment(dept);
dept.getEmployees().add(emp);
em.persist(emp);
The only difference between this sequence of operations and the ones we demonstrated earlier is that the find() call has been replaced with a call to getReference(). When the getReference() call is invoked, the provider may return a proxy to the Department entity without actually retrieving it from the database. So long as only its primary key is accessed, Department data does not need to be fetched. Instead, when the Employee is persisted, the primary key value will be used to create the foreign key to the corresponding Department entry. The getReference() call is effectively a performance optimization that removes the need to retrieve the target entity instance.
There are some drawbacks to using getReference() that must be understood. The first is that if a proxy is used, then it may throw an EntityNotFoundException exception if it is unable to locate the real entity instance when an attribute other the primary key is accessed. The assumption with getReference() is that you are sure the entity with the correct primary key exists. If, for some reason, an attribute other than the primary key is accessed and the entity does not exist, then an exception will be thrown. A corollary to this is that the object returned from getReference() may not be safe to use if it is no longer managed. If the provider returns a proxy, it will be dependent on there being an active persistence context to load entity state.
Given the very specific situation in which getReference() may be used, find() should be used in virtually all cases. The in-memory cache of a good persistence provider is effective enough that the performance cost of accessing an entity via its primary key will not usually be noticed. In the case of TopLink Essentials, it has a fully integrated shared object cache, so not only is local persistence context management efficient, but also all threads on the same server can benefit from the shared contents of the cache. The getReference() call is a performance optimization that should be used only when there is evidence to suggest that it will actually benefit the application.
And for the find( ) method, the book says
The find() operation returns a managed entity instance in all cases except when invoked outside of a transaction on a transaction-scoped entity manager. In this case, the entity instance is returned in a detached state. It is not associated with any persistence context.
Since the question does not say that the code is executed outside a transation, we can not say anything about l1.