java - 为什么 Spring ORM JpaTransactionManager 使用 native 实体管理器工厂?

标签 java spring hibernate spring-data-jpa spring-orm

使用 native 对象创建实体管理器 jps 事务时是否有任何特定原因?

   EntityManagerFactory emf = this.getEntityManagerFactory();
   if (emf instanceof EntityManagerFactoryInfo) {
            emf = 
           ((EntityManagerFactoryInfo)emf).getNativeEntityManagerFactory();
   }

我们的要求是使用 Proxy (Created) 而不是原生对象,我们围绕 getSession 方法创建了 aspect 以动态添加租户 id(Discriminator Column) 以供查询

谢谢, 毗湿奴

最佳答案

中肯的解释:

native EntityManagerFactory 在 JpaTransactionManagercreateEntityManagerForTransaction() 方法中解包的原因是因为仍然使用代理稍后会创建一个扩展 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/

相关文章:

xml - 从 XML 到 XML 文档的 XSLT 转换

java - 使用@JoinTable的@ManyToMany注释的JPA问题

java - JFrame背景颜色不会改变

java - FileChannel 返回 Assets 文件夹中文件的错误文件大小

java - 如何检测记录被锁定时间过长?

java - Spring 3.0 无法加载属性

java - 创建数组列表

java - Hibernate 逆向工程组合键创建额外的 ID 类

java - Spring Batch-MySQL问题

java - 将详细信息插入数据库时​​出现错误