我知道这一点:
Persistence.createEntityManagerFactory("persistence-unit-name");
JPA持久性机制读取“persistence.xml”文件,查找名为“persistence-unit-name”的持久性单元,并基于它构造EntityManagerFactory。
我的问题是,如何强制JPA 获取与“persistence.xml”不同的文件?例如,“persistence-test.xml”。
答案 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)
我认为你不能。这样做的好方法是:
persistence-test.xml
并呈现Map<String, String>
属性,并且。Persistence.createEntityManagerFactory(persistenceUnitName, Map properties)
。这样,它就会从properties
地图中读取,而不是从persistence.xml
读取。答案 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>
注释)。