何时使用 EntityManager.find() vs EntityManager.getReference() 与 JPA
我遇到过一种情况(我认为这很奇怪,但可能很正常),我使用EntityManager.getReference(LObj.getClass(),LObj.getId())来获取数据库实体,然后将返回的对象传递到另一个表中。
所以基本上流程是这样的:
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); ... } }
我得到以下异常“java.lang.IllegalArgumentException:未知实体:com.my.persistence.L$$EnhancerByCGLIB$$3e7987d0”
在研究了一段时间后,我终于发现,正是因为我使用了EntityManager.getReference()方法,我才得到上述异常,因为该方法返回了代理。
这让我想知道,什么时候建议使用EntityManager.getReference()方法而不是EntityManager.find()方法?
EntityManager.getReference() 如果找不到正在搜索的实体,它会抛出一个 EntityNotFoundException,这本身就非常方便。EntityManager.find() 方法在找不到实体时仅返回 null。
关于事务边界,在我看来,在将新找到的实体传递给新事务之前,您需要使用 find() 方法。如果您使用getReference()方法,那么您可能会遇到与我类似的情况,但上述例外。