title: When to use EntityManager.find() vs EntityManager.getReference() with JPA
body: <p>I have come across a situation (which I think is weird but is possibly quite normal) where I use the EntityManager.getReference(LObj.getClass(), LObj.getId()) to get a database entity and then pass the returned object to be persisted in another table.</p>
  
  <p>So basically the flow was like this:</p>
  
  <pre>
  class TFacade{
  
    createT(FObj, AObj) {
      T TObj = new T();
      TObj.setF(FObj);
      TObj.setA(AObj);
      ...
      EntityManager.persist(TObj);
      ...
      L LObj = A.getL();
      FObj.setL(LObj);
      FFacade.editF(FObj);
    }
  }
  
  @TransactionAttributeType.REQUIRES_NEW
  class FFacade{
  
    editF(FObj){
      L LObj = FObj.getL();
      LObj = EntityManager.getReference(LObj.getClass(), LObj.getId());
      ...
      EntityManager.merge(FObj);
      ...
      FLHFacade.create(FObj, LObj);
    }
  }
  
  @TransactionAttributeType.REQUIRED
  class FLHFacade{
  
    createFLH(FObj, LObj){
      FLH FLHObj = new FLH();
      FLHObj.setF(FObj);
      FLHObj.setL(LObj);
      ....
      EntityManager.persist(FLHObj);
      ...
    }
  }
  
  </pre>
  
  <p>I was getting the following exception "java.lang.IllegalArgumentException: Unknown entity: com.my.persistence.L$$EnhancerByCGLIB$$3e7987d0"</p>
  
  <p>After looking into it for a while, I finally figured out that it was because I was using the EntityManager.getReference() method that I was getting the above exception as the method was returning a proxy.</p>
  
  <p>This makes me wonder, <em>when is it advisable to use the EntityManager.getReference() method instead of the EntityManager.find() method</em>? </p>
  
  <p>EntityManager.getReference() throws an EntityNotFoundException if it cant find the entity being searched for which is very convenient in itself. EntityManager.find() method merely returns null if it cant find the entity.</p>
  
  <p>With regards to transaction boundaries, sounds to me like you would need to use the find() method before passing the newly found entity to a new transaction. If you use the getReference() method then you would probably end up in a situation similar to mine with the above exception.</p>