1

我的persistence.xml 中有许多持久性单元,一个是postgreSQL 模式。

我在需要时通过动态创建 EntityManagerFactory 来实例化我的 EntityManager:

EntityManagerFactory emf = Persistence.createEntityManagerFactory(schemaToChoose);
EntityManager em = emf.createEntityManager();

它工作正常。但因此,我不使用容器注入。

现在,我想知道这种方式是否不会花费太多资源?

我可能不太了解 JPA 缓存,但我相信实体存储在 em 缓存和 emf 缓存中,有 2 个级别。因此,当我每次实例化 em 和 emf 时,我可能会丢失 JPA 缓存,因此,我也每次都重新创建它。

我有 2 个问题:每次 emf 和 em 影响性能时可以实例化吗?我应该注入尽可能多的 em 我有模式而不是保留缓存吗?

谢谢

4

2 回答 2

2

EntityManagerFactory 是一个重量级的、长期创建的对象。它应该只创建一次,然后重复使用。实际上,每次创建它时,它都会解析 persistence.xml 文件,计算每个实体的映射元数据等。

如果您在 Java EE 容器中运行,那么您绝对应该让容器为您实例化它,并将实体管理器注入您的 EJB。

我发现一个应用程序使用多个数据库shemas 很奇怪。为什么会这样?

关于缓存:有一个与实体管理器关联的一级缓存(它是一个短暂的缓存,通常与事务具有相同的生命周期。也可能有一个二级缓存,与实体管理器工厂,但默认情况下处于关闭状态,如果启用,则只能用于某些实体并谨慎配置。

于 2012-11-23T09:39:28.407 回答
0

你基本上有一个多租户模式。EJB 注入不能很好地处理这个问题。

EntityManagerFactory 不是您想要多次创建的东西,并且确实包含共享缓存。(共享缓存默认值不是 JPA 指定的,它在 EclipseLink 中默认开启,但可以通过 JPA 缓存模式和 @Cacheable 和 @Cache 进行配置)。

我会为您的工厂推荐某种注册表。也许这甚至是一个应用程序对象,比如你的 Universe。

public class Universe {
    static Map<String, Universe> universes;
    EntityManagerFactory emf;

    public static Universe getUniverse(String schema) {
      ... hopefully you get the idea ...
    }
    public EntityManagerFactory getEntityManagerFactory() {
        return emf;
    }
}

另外,我建议您查看 EclipseLink 的多租户支持,

http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm#BABEGBIJ

于 2012-11-26T14:11:34.350 回答