我正在尝试使用嵌入式 EJB 容器测试我的 EJB。在生产中,我依赖于应用服务器中配置的 JTA 数据源。但是,在测试期间,我想连接到不同的数据库(内存 Derby)。
问题是我看不到如何告诉 EJB 容器通过连接到内存中的 derby DB 来覆盖我的生产 persistence.xml(在 src/main/resources/META-INF 中)中定义的 JTA 数据源。JTA 数据源在 persistence.xml 文件中定义,如下所示:
<jta-data-source>jdbc/myDS</jta-data-source>
尝试 1:使用测试 persistence.xml
我尝试创建一个测试 persistence.xml 文件(在 src/test/resources/META-INF 中),它定义:
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:myDataBase;create=true;" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="password" />
但这没有实际意义,因为当我指定 EJB 容器以使用被测模块时
Map properties = new HashMap();
properties.put(EJBContainer.MODULES, new File[] { new File("target/classes/") });
ec = EJBContainer.createEJBContainer(properties);
容器只使用主 persistence.xml 文件而不是我的测试文件。
尝试 2:将主类和测试类合并到一个分解模块中
我认为使这种方法起作用的唯一方法是使用此处描述的方法- 将被测模块的类复制到单独的位置(例如 target/ejb-testing-classes),然后复制测试 persistence.xml文件放在顶部,然后将这个新位置指定给 EJB 容器:
Map properties = new HashMap();
properties.put(EJBContainer.MODULES, new File[] { new File("target/ejb-testing-classes/") });
ec = EJBContainer.createEJBContainer(properties);
但这似乎不必要地笨拙。如果我尝试在容器中部署预打包的模块(即依赖项),将来也可能会出现问题,因为我需要在合并之前分解 jar。
我的愿望:EJB 容器的数据源覆盖属性
我认为可能有其他属性可以传递到 EJB 容器中,但到目前为止,我只能找到适合openEJB或websphere的属性。我正在使用嵌入式 Glassfish 来提供我的嵌入式 EJB 容器,因为它是目标平台。(我现在找到了 glassfish 属性 - 请参阅下面的更新 #1)
当然,每个尝试使用嵌入式 EJB 容器和与生产数据库不同的数据源测试 EJB 的人都遇到过这个问题。甚至这个人也只是在这一点上放弃并使用了默认的嵌入式数据库,这对我来说不是一个选项。
任何帮助将非常感激。
更新 1:我找到了Glassfish EJB 容器接受的属性列表,起初我似乎可以使用以下属性
org.glassfish.ejb.embedded.glassfish.configuration.file
在 domain.xml 中定义数据源并将容器指向它。但是,根据源代码,除非还设置了 installation.root 属性,否则此属性将被忽略 - 这意味着需要预先安装 glassfish 才能运行我的测试。这会不可接受地降低我的 Maven 项目的可移植性。:(
更新 2:我为这个问题创建了一个JIRA 问题,并建议为 glassfish EJB 容器引入属性,该容器允许配置 JTA 数据源。