使用 native 对象创建实体管理器 jps 事务时是否有任何特定原因?
EntityManagerFactory emf = this.getEntityManagerFactory();
if (emf instanceof EntityManagerFactoryInfo) {
emf =
((EntityManagerFactoryInfo)emf).getNativeEntityManagerFactory();
}
我们的要求是使用 Proxy (Created) 而不是原生对象,我们围绕 getSession 方法创建了 aspect 以动态添加租户 id(Discriminator Column) 以供查询
谢谢, 毗湿奴
最佳答案
中肯的解释:
native EntityManagerFactory 在 JpaTransactionManager 的 createEntityManagerForTransaction() 方法中解包的原因是因为仍然使用代理稍后会创建一个扩展 EntityManager 而不是 transaction-scoped 一个。在常规事务 session 的情况下,后者是我们想要的。
如果我们仍然使用代理会发生什么:
因为代理将所有调用委托(delegate)给 ManagedEntityManagerFactoryInvocationHandler,所以我们希望从中获取事务范围实体管理器的 createEntityManager() 调用也将被委托(delegate).
如果我们查看上述处理程序的 invoke() 方法的实现,我们会发现它从 AbstractEntityManagerFactoryBean 调用了 invokeProxyMethod()看到它专门触发了扩展事务管理器的创建,而不是事务范围的管理器。这可能只是 Spring 开发人员的设计选择。
Object invokeProxyMethod(Method method, @Nullable Object[] args) throws Throwable {
// unrelated code here
if (method.getName().equals("createEntityManager") && args != null && args.length > 0 &&
args[0] == SynchronizationType.SYNCHRONIZED) {
EntityManager rawEntityManager = (args.length > 1 ?
getNativeEntityManagerFactory().createEntityManager((Map<?, ?>) args[1]) :
getNativeEntityManagerFactory().createEntityManager());
// we get an extended entity manager
return ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, true);
}
// more unrelated code here
Object retVal = method.invoke(getNativeEntityManagerFactory(), args);
if (retVal instanceof EntityManager) {
EntityManager rawEntityManager = (EntityManager) retVal;
retVal = ExtendedEntityManagerCreator.createApplicationManagedEntityManager(rawEntityManager, this, false);
}
// in the final path, we also get an extended entity manager
return retVal;
}
我会研究一些方法来规避您的问题:
您可以尝试子类化 JpaTransactionManager 并用最小的更改覆盖 createEntityManagerForTransaction() 以适应您稍后提到的方面的使用。但是,由于上述与扩展实体管理器相关的解释,简单地不解包 EntityManagerFactory 代理可能不是您想要的。
您可能想要研究的另一件事是更改您提到的方面,以不需要使用 Spring 的 entityManagerFactory 代理并与 native 对象一起玩。作为最后的手段,您可以尝试子类化并覆盖整个解决方案中提到的多个 Spring ORM 类的方法,以便您同时适应 Spring 的行为和您的方面。
关于java - 为什么 Spring ORM JpaTransactionManager 使用 native 实体管理器工厂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52096184/