JPA使用替代“persistence.xml”

时间:2011-08-29 08:30:08

标签: java hibernate jpa ejb

我知道这一点:

Persistence.createEntityManagerFactory("persistence-unit-name");

JPA持久性机制读取“persistence.xml”文件,查找名为“persistence-unit-name”的持久性单元,并基于它构造EntityManagerFactory。

我的问题是,如何强制JPA 获取与“persistence.xml”不同的文件?例如,“persistence-test.xml”。

6 个答案:

答案 0 :(得分:18)

虽然单个JPA提供商可能提供一种方法,但没有标准化的JPA方法。我建议使用标准方法为main和test提供不同的类路径。

例如,如果你使用Maven,并且你有两个META-INF/persistence.xml个文件,一个在src/main/resources,一个在src/test/resources,那么测试会选择src/test/resources中的一个,因为Maven将测试类/资源放在类路径中的主类/资源之前。您可以轻松地将Ant配置为以类似方式工作。

如果您需要更高级的逻辑,请考虑使用Spring's JPA support。它可以让您处理integrating multiple persistence.xml files等高级情况。

答案 1 :(得分:15)

在EclipseLink中,您可以执行以下操作:

Properties pros = new Properties();

pros.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, 
                 "META-INF/persistence-alternative.xml");


EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory("pu-name", pros);

答案 2 :(得分:4)

我认为你不能。这样做的好方法是:

答案 3 :(得分:2)

所以我们希望有两个单独的persistence.xml个文件。一个应该只由生产配置读取,另一个用于测试。我们的想法是重命名或隐藏生产文件。

战争解决方案

不要将persistence.xml放入src\main\resources\META-INF\。而是将其放入src\main\webapp\WEB-INF\classes\META-INF\。那是文件所在的位置,在这个位置它不会被测试看到。

此解决方案适用于gradle环境,但我希望其他人也能这样做。

Jar解决方案

将生产文件重命名为persistence-ee.xml。现在我们已经完成了测试配置。对于生产,我们必须采用一些处理。每个环境都有自己的方式,这就是我在gradle中的方式:

tasks.withType(Jar) {
  rename { fileName ->
    fileName == "persistence-ee.xml" ? "persistence.xml" : fileName;
  }
}

在我的应用程序中,仅在部署时需要生成persistence.xml文件,即jar / war包中。这些是唯一可以看到此文件的地方。如果没有双persistence,我就无法启动数据库。主要原因是使用jta-data-source,另一个是:2个单独的命名持久性单元。

答案 4 :(得分:1)

如果您使用OpenEJB来推动测试,您可以使用您想要的任何JPA提供商完成您想要的任务。类似的问题和相关的答案:

How to instruct Maven to ignore my main/resources/persistence.xml in favor of test/...?

答案 5 :(得分:1)

您可以在Spring中配置Hibernate而不使用persistence.xml,如下所示:

@EnableTransactionManagement

由于您没有使用persistence.xml,您应该创建一个返回DataSource的bean,您可以在上面设置数据源的方法中指定它:

@Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}

然后在此配置文件上使用@Transactional注释。现在当你放置那个注释时,你必须创建一个最后一个bean:

EntityManager

现在,不要忘记对那些处理数据库的方法使用@Repository注释。

最后,不要忘记在您的存储库中注入incrementVote(comment) { comment.votes++ //increment the vote count const businesschildKey = comment['.key']; //get key of modified comment delete comment['.key']; //Firebase doesn't know how to handle them but can use VueFire to get around that. this.$firebaseRefs.comments.child(businesschildKey).set(comment) //Updates Firebase record matching key }, (此存储库类应该对其进行<sstream>注释)。