我有一个带有多个模式的数据库,所以我有一个带有倍数 <persistence-unit />
(名为01,02,...)的persistence.xml文件 .
Problematic : 我想创建一个EntityManager动态函数的某些用户标准 .
我测试了2个案例 .
第一种情况:基本上,我测试了这段代码(在无状态EJB中):
String criteria = "01";
EntityManagerFactory emf = Persistence.createEntityManagerFactory(criteria);
EntityManager em = emf.createEntityManager();
Joueur joueur = new Joueur(); // Joueur is an Entity
joueur.setPseudo("olivier");
em.persist(joueur);
但我收到了例外:
引起:异常[EclipseLink-4002](Eclipse Persistence Services - 2.3.2.v20111125-r10461):org.eclipse.persistence.exceptions.DatabaseException内部异常:org.postgresql.util.PSQLException:ERREUR:la transactionestannulée ,les commandes sontignoréesjusqu'àlafin du bloc de la transaction
我想,(在一些Stackoverflow帖子的帮助下),我的EntityManager没有“链接”到我的事务上下文,因为它没有被容器注入 .
第二种情况:因此,我使用了注射:
@PersistenceContext(unitName="00")
private EntityManager em00;
@PersistenceContext(unitName="01")
private EntityManager em01;
我的功能代码:
String criteria = "01";
EntityManager em = getEm(criteria);
...
和getEm()方法:
private EntityManager getEm(String criteria){
if (criteria == "00")
return em00;
else if (criteria == "01")
return em01;
return null;
}
没问题,这是工作,但我必须注入尽可能多的EntityManagers,我有持久性单位 .
-
如果我有50个架构会有什么代价......?
-
有没有办法真正动态管理实体经理? (仅限1个EntityManger)
-
如果我必须为每个模式创建1个EntityManager,即使我不使用它,我如何改进我的代码以尽可能少地消耗资源?
感谢您提供建议和反馈
EDIT :
我的配置文件:
Persistence.xml:
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="00" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/sim/00</jta-data-source>
<mapping-file>orm_00_beta.xml</mapping-file>
<class>com.sim.entities.Joueur</class>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
<persistence-unit name="01" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/sim/01</jta-data-source>
<mapping-file>orm_01_beta2.xml</mapping-file>
<class>com.sim.entities.Joueur</class>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
</persistence>
orm_00_beta.xml:
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>beta</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
orm_01_beta2.xml:
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>beta2</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
2 回答
在使用应用程序管理的持久性单元时,您需要将“eclipselink.target-server”设置为您正在使用的应用程序服务器(某些服务器会自动设置,然后使用容器管理的持久性单元) . 然后,EntityManager将与创建时处于活动状态的JTA事务绑定 . 如果在JTA事务开始之前创建EntityManager,则可以使用joinTransaction() .
如果仍有问题,请包括您正在使用的服务器以及完整的异常堆栈跟踪 .
如果您有很多模式,可以考虑使用EclipseLink多租户支持,它允许每个租户拥有自己的模式 .
http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm#BABEGBIJ
通常你没有50个模式 . 我不担心注入的成本,因为通常EJB容器有一个已经打开的连接池,可以注入 . 所以开销很小 .
AFAIK,JPA不允许动态实体经理 .
如果您关心资源,我建议避免使用EclipseLink(我对EclipseLink EJB的使用体验非常糟糕)
为了优化一点,我会尝试在这里使用工厂模式 . 创建一个Bean,它将为您提供EntityManagers . 而不是注入几个PersistenceContext,你将有一个注入方法,如:
另一种选择是将所有注入移动到AbstractBean . 所有其他bean都继承自AbstractBean .