JPA使用替代“persistence.xml”

我知道这说明:

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

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

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

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

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

如果您需要更高级的逻辑,请考虑使用Spring的JPA支持 。 它将让您处理高级情况,如集成多个persistence.xml文件 。

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

 Properties pros = new Properties(); pros.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/persistence-alternative.xml"); EntityManagerFactory factory = Persistence.createEntityManagerFactory("pu-name", pros); 

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

  • 创建一个工厂,它将读取您的persistence-test.xml并呈现Map属性,以及。
  • 调用Persistence.createEntityManagerFactory(persistenceUnitName, Map properties) 。 这样,它从properties映射中读取而不是从persistence.xml读取。

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

如何指示Maven忽略我的main / resources / persistence.xml以支持test / …?

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

 @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { Map properties = new Hashtable<>(); properties.put("javax.persistence.schema-generation.database.action", "none"); HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(adapter); factory.setDataSource(this.springJpaDataSource()); factory.setPackagesToScan("package name"); factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE); factory.setValidationMode(ValidationMode.NONE); factory.setJpaPropertyMap(properties); return factory; } 

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

 @Bean public DataSource springJpaDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUrl("jdbc:mysql://localhost/SpringJpa"); dataSource.setUsername("tomcatUser"); dataSource.setPassword("password1234"); return dataSource; } 

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

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

现在,不要忘记对那些处理DB的方法使用@Transactional Annotation。

最后,不要忘记在您的存储库中注入EntityManager (此存储库类应该对其进行@Repository注释)。

所以我们想要有两个独立的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个独立的命名持久性单元。