2013-03-01 238 views
1

JPA是否支持可选的持久性单元,如果是的话如何配置?JPA中的可选持久性单元(使用多个持久性单元时)

我有一个持久性单元,这是我的主要数据库。

然后我配置了另一个我刚从数据库中读取对象来做一些检查。为了避免混淆多个数据源上的事务,我设置了第二个数据源jta="false"

但我希望能够检查是否有第二个数据源被定义,只有在它存在时才使用它。如果没有定义,我想简单地跳过我的支票。

问题是,我找不到如何使此选项。如果未配置第二数据源我从JBoss中部署扫描器New missing/unsatisfied dependencies错误时,我的战争部署:

service jboss.naming.context.java.secondDatasource (missing) dependents: [service jboss.persistenceunit."de.my.war#secondDatasource"] 

(顺便说一句:我使用JBoss 7.1.0和standard.xml配置的数据源 - 如果该信息与任何相关性)。

任何提示?

回答

3

我不确定这是可能的XML配置,这基本上是如何在大多数情况下使用JPA的约定。尝试寻找一个编程方法。

也许你可以通过编程的方式将数据源查找为JNDI资源,如果找到了,你可以自己build an EntityManager。在CDI的帮助下,它可能不会像你想象的那么困难。

@Produces 
@MyAlterNativeEntityManager 
public EntityManager getEntityManager { 
    EntityManager entityManager = null; 
    if(jndiLookupMySecondDatasource()){ 
     entityManager = buildEntityManagerProgrammatically(...); 
    } 
    return entityManager; 
} 

当然,如果没有找到数据源,一个空的EntityManager将返回但随后调用代码,你可以简单地检查它是否被初始化,并且只使用,如果它是。 希望能帮助你把握正确的道路。

+0

感谢您的想法。我认为这已经发生,当我的'persistence.xml'处理。但是我会检查这个...... – Jens 2013-03-06 14:46:27

+0

当然,但这样你甚至不必在persistence.xml中声明第二个数据源! – 2013-03-06 21:57:11

+0

@BalzásMáriaNémeth:对不起,我迟到了。如果存在通过JNDI发现的'datasource',我尝试了自己构建'EntityManager'的解决方案。但是:我不知道如何在我自己创建的'EntityManager'上设置找到的'datasource'。 'EntityManagerFactory'。它只接受'属性'来创建一个。但我手边有一个'datasouce'。我想过自己映射所有必要的属性,但密码是我在'datasource'上找不到的。有没有办法让创建的'EntityManager'使用我的'datasource'? – Jens 2013-03-18 10:10:32

1

在JPA标准:

  • 每个的EntityManagerFactory(EMF)必须涉及一个PersistentUnit(PU) - 不可能有多个PersistenceUnits也不为零PersistenceUnits。
  • 每个EntityManager(EM)实例都是从EMF创建的,因此也有一个PU。当然,可以从EMF创建多个EM,全部使用相同的PU。
  • 可以配置PU使用硬编码

    明确地使用其针对每个EMF

    EntityManagerFactory的电动势= Persistence.createEntityManagerFactory( “的EmployeeService”);

    或通过注射使用注释

    @PersistenceUnit( “的EmployeeService”) EntityManagerFactory的电动势的电动势;

    或者可以让它保持空白,只需选取persistence.xml中配置的默认PU。

  • 可以通过使用注释注入EM来配置对每个EM显式使用哪个PU。这里的代码根本不涉及EMF(让容器不可见地引用EMF)

    @PersistenceContext(unitName =“EmployeeService”) EntityManager em;

在所有这些可选PU的想法没有任何意义。如果您正在使用JPA EM,则必须提交PU。

选项:

  1. 编辑的persistence.xml为具有两个不同的物理数据库实例之间的相同的逻辑持久性单元“开关”。不符合全部要求 - 仍会从替代数据源读取值。
  2. 根据Balazs Maria Nemeth的解决方案,查找/注入一个环境变量(不管是否“调试”)并以编程方式在不同数据源之间轻弹。不符合全部要求,因为它仍然会从替代数据源读取值。
  3. 查找/注入一个环境变量(不管是否为“调试”)并适当地为替代EM运行/排除代码。

3只是满足全部要求的选项。例如: -

// Inject environment setting. Resource annotation works with/without CDI - 
// just doesn't give scoping support, which isn't required here. 
@Resource boolean debugMode; 

if (debugMode) { 
    @PersistenceContext(unitName="DebugPersistenceUnit") 
    EntityManager debugEM; 

    Employee emp = debugEM.find(Employee.class, empId); 
} 
在web.xml或ejb.xml

然后包括ENV条目:

<env-entry> 
    <description> 
    Only set this true in a debugging environment 
    </description> 
    <env-entry-name>debugMode</env-entry-name> 
    <env-entry-type>java.lang.Boolean</env-entry-type> 
    <env-entry-value>true</env-entry-value> 
</env-entry>